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 if (!refiner) PetscFunctionReturn(0); 179 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 180 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 181 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 182 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 183 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 184 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 185 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 186 switch (refiner) { 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 if (!refiner) PetscFunctionReturn(0); 988 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 989 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 990 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 991 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 992 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 993 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 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 switch (refiner) { 997 case 1: 998 /* Simplicial 2D */ 999 /* 1000 2 1001 |\ 1002 | \ 1003 | \ 1004 | \ 1005 | C \ 1006 | \ 1007 | \ 1008 2---1---1 1009 |\ D / \ 1010 | 2 0 \ 1011 |A \ / B \ 1012 0---0-------1 1013 */ 1014 /* All cells have 3 faces */ 1015 for (c = cStart; c < cEnd; ++c) { 1016 const PetscInt newp = cStartNew + (c - cStart)*4; 1017 const PetscInt *cone, *ornt; 1018 PetscInt coneNew[3], orntNew[3]; 1019 1020 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1021 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1022 /* A triangle */ 1023 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1024 orntNew[0] = ornt[0]; 1025 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1026 orntNew[1] = -2; 1027 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1028 orntNew[2] = ornt[2]; 1029 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1030 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1031 #if 1 1032 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); 1033 for (p = 0; p < 3; ++p) { 1034 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); 1035 } 1036 #endif 1037 /* B triangle */ 1038 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1039 orntNew[0] = ornt[0]; 1040 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1041 orntNew[1] = ornt[1]; 1042 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1043 orntNew[2] = -2; 1044 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1045 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1046 #if 1 1047 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); 1048 for (p = 0; p < 3; ++p) { 1049 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); 1050 } 1051 #endif 1052 /* C triangle */ 1053 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1054 orntNew[0] = -2; 1055 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1056 orntNew[1] = ornt[1]; 1057 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1058 orntNew[2] = ornt[2]; 1059 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1060 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1061 #if 1 1062 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); 1063 for (p = 0; p < 3; ++p) { 1064 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); 1065 } 1066 #endif 1067 /* D triangle */ 1068 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1069 orntNew[0] = 0; 1070 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1071 orntNew[1] = 0; 1072 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1073 orntNew[2] = 0; 1074 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1075 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1076 #if 1 1077 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); 1078 for (p = 0; p < 3; ++p) { 1079 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); 1080 } 1081 #endif 1082 } 1083 /* Split faces have 2 vertices and the same cells as the parent */ 1084 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1085 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1086 for (f = fStart; f < fEnd; ++f) { 1087 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1088 1089 for (r = 0; r < 2; ++r) { 1090 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1091 const PetscInt *cone, *ornt, *support; 1092 PetscInt coneNew[2], coneSize, c, supportSize, s; 1093 1094 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1095 coneNew[0] = vStartNew + (cone[0] - vStart); 1096 coneNew[1] = vStartNew + (cone[1] - vStart); 1097 coneNew[(r+1)%2] = newv; 1098 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1099 #if 1 1100 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1101 for (p = 0; p < 2; ++p) { 1102 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); 1103 } 1104 #endif 1105 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1106 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1107 for (s = 0; s < supportSize; ++s) { 1108 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1109 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1110 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1111 for (c = 0; c < coneSize; ++c) { 1112 if (cone[c] == f) break; 1113 } 1114 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1115 } 1116 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1117 #if 1 1118 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1119 for (p = 0; p < supportSize; ++p) { 1120 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); 1121 } 1122 #endif 1123 } 1124 } 1125 /* Interior faces have 2 vertices and 2 cells */ 1126 for (c = cStart; c < cEnd; ++c) { 1127 const PetscInt *cone; 1128 1129 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1130 for (r = 0; r < 3; ++r) { 1131 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1132 PetscInt coneNew[2]; 1133 PetscInt supportNew[2]; 1134 1135 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1136 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1137 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1138 #if 1 1139 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1140 for (p = 0; p < 2; ++p) { 1141 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); 1142 } 1143 #endif 1144 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1145 supportNew[1] = (c - cStart)*4 + 3; 1146 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1147 #if 1 1148 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1149 for (p = 0; p < 2; ++p) { 1150 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); 1151 } 1152 #endif 1153 } 1154 } 1155 /* Old vertices have identical supports */ 1156 for (v = vStart; v < vEnd; ++v) { 1157 const PetscInt newp = vStartNew + (v - vStart); 1158 const PetscInt *support, *cone; 1159 PetscInt size, s; 1160 1161 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1162 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1163 for (s = 0; s < size; ++s) { 1164 PetscInt r = 0; 1165 1166 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1167 if (cone[1] == v) r = 1; 1168 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1169 } 1170 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1171 #if 1 1172 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1173 for (p = 0; p < size; ++p) { 1174 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); 1175 } 1176 #endif 1177 } 1178 /* Face vertices have 2 + cells*2 supports */ 1179 for (f = fStart; f < fEnd; ++f) { 1180 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1181 const PetscInt *cone, *support; 1182 PetscInt size, s; 1183 1184 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1185 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1186 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1187 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1188 for (s = 0; s < size; ++s) { 1189 PetscInt r = 0; 1190 1191 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1192 if (cone[1] == f) r = 1; 1193 else if (cone[2] == f) r = 2; 1194 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1195 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1196 } 1197 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1198 #if 1 1199 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1200 for (p = 0; p < 2+size*2; ++p) { 1201 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); 1202 } 1203 #endif 1204 } 1205 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1206 break; 1207 case 2: 1208 /* Hex 2D */ 1209 /* 1210 3---------2---------2 1211 | | | 1212 | D 2 C | 1213 | | | 1214 3----3----0----1----1 1215 | | | 1216 | A 0 B | 1217 | | | 1218 0---------0---------1 1219 */ 1220 /* All cells have 4 faces */ 1221 for (c = cStart; c < cEnd; ++c) { 1222 const PetscInt newp = (c - cStart)*4; 1223 const PetscInt *cone, *ornt; 1224 PetscInt coneNew[4], orntNew[4]; 1225 1226 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1227 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1228 /* A quad */ 1229 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1230 orntNew[0] = ornt[0]; 1231 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1232 orntNew[1] = 0; 1233 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1234 orntNew[2] = -2; 1235 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1236 orntNew[3] = ornt[3]; 1237 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1238 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1239 #if 1 1240 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); 1241 for (p = 0; p < 4; ++p) { 1242 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); 1243 } 1244 #endif 1245 /* B quad */ 1246 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1247 orntNew[0] = ornt[0]; 1248 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1249 orntNew[1] = ornt[1]; 1250 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1251 orntNew[2] = 0; 1252 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1253 orntNew[3] = -2; 1254 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1255 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1256 #if 1 1257 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); 1258 for (p = 0; p < 4; ++p) { 1259 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); 1260 } 1261 #endif 1262 /* C quad */ 1263 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1264 orntNew[0] = -2; 1265 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1266 orntNew[1] = ornt[1]; 1267 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1268 orntNew[2] = ornt[2]; 1269 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1270 orntNew[3] = 0; 1271 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1272 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1273 #if 1 1274 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); 1275 for (p = 0; p < 4; ++p) { 1276 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); 1277 } 1278 #endif 1279 /* D quad */ 1280 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1281 orntNew[0] = 0; 1282 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1283 orntNew[1] = -2; 1284 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1285 orntNew[2] = ornt[2]; 1286 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1287 orntNew[3] = ornt[3]; 1288 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1289 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1290 #if 1 1291 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); 1292 for (p = 0; p < 4; ++p) { 1293 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); 1294 } 1295 #endif 1296 } 1297 /* Split faces have 2 vertices and the same cells as the parent */ 1298 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1299 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1300 for (f = fStart; f < fEnd; ++f) { 1301 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1302 1303 for (r = 0; r < 2; ++r) { 1304 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1305 const PetscInt *cone, *ornt, *support; 1306 PetscInt coneNew[2], coneSize, c, supportSize, s; 1307 1308 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1309 coneNew[0] = vStartNew + (cone[0] - vStart); 1310 coneNew[1] = vStartNew + (cone[1] - vStart); 1311 coneNew[(r+1)%2] = newv; 1312 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1313 #if 1 1314 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1315 for (p = 0; p < 2; ++p) { 1316 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); 1317 } 1318 #endif 1319 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1320 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1321 for (s = 0; s < supportSize; ++s) { 1322 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1323 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1324 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1325 for (c = 0; c < coneSize; ++c) { 1326 if (cone[c] == f) break; 1327 } 1328 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1329 } 1330 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1331 #if 1 1332 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1333 for (p = 0; p < supportSize; ++p) { 1334 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 1335 } 1336 #endif 1337 } 1338 } 1339 /* Interior faces have 2 vertices and 2 cells */ 1340 for (c = cStart; c < cEnd; ++c) { 1341 const PetscInt *cone; 1342 PetscInt coneNew[2], supportNew[2]; 1343 1344 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1345 for (r = 0; r < 4; ++r) { 1346 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1347 1348 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1349 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1350 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1351 #if 1 1352 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1353 for (p = 0; p < 2; ++p) { 1354 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); 1355 } 1356 #endif 1357 supportNew[0] = (c - cStart)*4 + r; 1358 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1359 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1360 #if 1 1361 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1362 for (p = 0; p < 2; ++p) { 1363 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); 1364 } 1365 #endif 1366 } 1367 } 1368 /* Old vertices have identical supports */ 1369 for (v = vStart; v < vEnd; ++v) { 1370 const PetscInt newp = vStartNew + (v - vStart); 1371 const PetscInt *support, *cone; 1372 PetscInt size, s; 1373 1374 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1375 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1376 for (s = 0; s < size; ++s) { 1377 PetscInt r = 0; 1378 1379 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1380 if (cone[1] == v) r = 1; 1381 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1382 } 1383 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1384 #if 1 1385 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1386 for (p = 0; p < size; ++p) { 1387 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); 1388 } 1389 #endif 1390 } 1391 /* Face vertices have 2 + cells supports */ 1392 for (f = fStart; f < fEnd; ++f) { 1393 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1394 const PetscInt *cone, *support; 1395 PetscInt size, s; 1396 1397 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1398 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1399 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1400 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1401 for (s = 0; s < size; ++s) { 1402 PetscInt r = 0; 1403 1404 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1405 if (cone[1] == f) r = 1; 1406 else if (cone[2] == f) r = 2; 1407 else if (cone[3] == f) r = 3; 1408 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1409 } 1410 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1411 #if 1 1412 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1413 for (p = 0; p < 2+size; ++p) { 1414 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); 1415 } 1416 #endif 1417 } 1418 /* Cell vertices have 4 supports */ 1419 for (c = cStart; c < cEnd; ++c) { 1420 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1421 PetscInt supportNew[4]; 1422 1423 for (r = 0; r < 4; ++r) { 1424 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1425 } 1426 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1427 } 1428 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1429 break; 1430 case 3: 1431 /* Hybrid Simplicial 2D */ 1432 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1433 cMax = PetscMin(cEnd, cMax); 1434 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1435 fMax = PetscMin(fEnd, fMax); 1436 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1437 /* Interior cells have 3 faces */ 1438 for (c = cStart; c < cMax; ++c) { 1439 const PetscInt newp = cStartNew + (c - cStart)*4; 1440 const PetscInt *cone, *ornt; 1441 PetscInt coneNew[3], orntNew[3]; 1442 1443 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1444 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1445 /* A triangle */ 1446 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1447 orntNew[0] = ornt[0]; 1448 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1449 orntNew[1] = -2; 1450 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1451 orntNew[2] = ornt[2]; 1452 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1453 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1454 #if 1 1455 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); 1456 for (p = 0; p < 3; ++p) { 1457 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); 1458 } 1459 #endif 1460 /* B triangle */ 1461 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1462 orntNew[0] = ornt[0]; 1463 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1464 orntNew[1] = ornt[1]; 1465 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1466 orntNew[2] = -2; 1467 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1468 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1469 #if 1 1470 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); 1471 for (p = 0; p < 3; ++p) { 1472 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); 1473 } 1474 #endif 1475 /* C triangle */ 1476 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1477 orntNew[0] = -2; 1478 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1479 orntNew[1] = ornt[1]; 1480 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1481 orntNew[2] = ornt[2]; 1482 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1483 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1484 #if 1 1485 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); 1486 for (p = 0; p < 3; ++p) { 1487 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); 1488 } 1489 #endif 1490 /* D triangle */ 1491 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1492 orntNew[0] = 0; 1493 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1494 orntNew[1] = 0; 1495 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1496 orntNew[2] = 0; 1497 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1498 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1499 #if 1 1500 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); 1501 for (p = 0; p < 3; ++p) { 1502 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); 1503 } 1504 #endif 1505 } 1506 /* 1507 2----3----3 1508 | | 1509 | B | 1510 | | 1511 0----4--- 1 1512 | | 1513 | A | 1514 | | 1515 0----2----1 1516 */ 1517 /* Hybrid cells have 4 faces */ 1518 for (c = cMax; c < cEnd; ++c) { 1519 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1520 const PetscInt *cone, *ornt; 1521 PetscInt coneNew[4], orntNew[4], r; 1522 1523 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1524 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1525 r = (ornt[0] < 0 ? 1 : 0); 1526 /* A quad */ 1527 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 1528 orntNew[0] = ornt[0]; 1529 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 1530 orntNew[1] = ornt[1]; 1531 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 1532 orntNew[2+r] = 0; 1533 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1534 orntNew[3-r] = 0; 1535 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1536 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1537 #if 1 1538 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); 1539 for (p = 0; p < 4; ++p) { 1540 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); 1541 } 1542 #endif 1543 /* B quad */ 1544 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 1545 orntNew[0] = ornt[0]; 1546 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 1547 orntNew[1] = ornt[1]; 1548 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1549 orntNew[2+r] = 0; 1550 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 1551 orntNew[3-r] = 0; 1552 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1553 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1554 #if 1 1555 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); 1556 for (p = 0; p < 4; ++p) { 1557 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); 1558 } 1559 #endif 1560 } 1561 /* Interior split faces have 2 vertices and the same cells as the parent */ 1562 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1563 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1564 for (f = fStart; f < fMax; ++f) { 1565 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1566 1567 for (r = 0; r < 2; ++r) { 1568 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1569 const PetscInt *cone, *ornt, *support; 1570 PetscInt coneNew[2], coneSize, c, supportSize, s; 1571 1572 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1573 coneNew[0] = vStartNew + (cone[0] - vStart); 1574 coneNew[1] = vStartNew + (cone[1] - vStart); 1575 coneNew[(r+1)%2] = newv; 1576 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1577 #if 1 1578 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1579 for (p = 0; p < 2; ++p) { 1580 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); 1581 } 1582 #endif 1583 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1584 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1585 for (s = 0; s < supportSize; ++s) { 1586 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1587 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1588 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1589 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 1590 if (support[s] >= cMax) { 1591 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 1592 } else { 1593 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1594 } 1595 } 1596 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1597 #if 1 1598 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1599 for (p = 0; p < supportSize; ++p) { 1600 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); 1601 } 1602 #endif 1603 } 1604 } 1605 /* Interior cell faces have 2 vertices and 2 cells */ 1606 for (c = cStart; c < cMax; ++c) { 1607 const PetscInt *cone; 1608 1609 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1610 for (r = 0; r < 3; ++r) { 1611 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1612 PetscInt coneNew[2]; 1613 PetscInt supportNew[2]; 1614 1615 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1616 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1617 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1618 #if 1 1619 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1620 for (p = 0; p < 2; ++p) { 1621 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); 1622 } 1623 #endif 1624 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1625 supportNew[1] = (c - cStart)*4 + 3; 1626 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1627 #if 1 1628 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1629 for (p = 0; p < 2; ++p) { 1630 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); 1631 } 1632 #endif 1633 } 1634 } 1635 /* Interior hybrid faces have 2 vertices and the same cells */ 1636 for (f = fMax; f < fEnd; ++f) { 1637 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1638 const PetscInt *cone, *ornt; 1639 const PetscInt *support; 1640 PetscInt coneNew[2]; 1641 PetscInt supportNew[2]; 1642 PetscInt size, s, r; 1643 1644 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1645 coneNew[0] = vStartNew + (cone[0] - vStart); 1646 coneNew[1] = vStartNew + (cone[1] - vStart); 1647 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1648 #if 1 1649 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1650 for (p = 0; p < 2; ++p) { 1651 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); 1652 } 1653 #endif 1654 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1655 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1656 for (s = 0; s < size; ++s) { 1657 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1658 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1659 for (r = 0; r < 2; ++r) { 1660 if (cone[r+2] == f) break; 1661 } 1662 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 1663 } 1664 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1665 #if 1 1666 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1667 for (p = 0; p < size; ++p) { 1668 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); 1669 } 1670 #endif 1671 } 1672 /* Cell hybrid faces have 2 vertices and 2 cells */ 1673 for (c = cMax; c < cEnd; ++c) { 1674 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1675 const PetscInt *cone; 1676 PetscInt coneNew[2]; 1677 PetscInt supportNew[2]; 1678 1679 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1680 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1681 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1682 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1683 #if 1 1684 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1685 for (p = 0; p < 2; ++p) { 1686 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); 1687 } 1688 #endif 1689 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1690 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1691 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1692 #if 1 1693 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1694 for (p = 0; p < 2; ++p) { 1695 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); 1696 } 1697 #endif 1698 } 1699 /* Old vertices have identical supports */ 1700 for (v = vStart; v < vEnd; ++v) { 1701 const PetscInt newp = vStartNew + (v - vStart); 1702 const PetscInt *support, *cone; 1703 PetscInt size, s; 1704 1705 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1706 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1707 for (s = 0; s < size; ++s) { 1708 if (support[s] >= fMax) { 1709 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1710 } else { 1711 PetscInt r = 0; 1712 1713 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1714 if (cone[1] == v) r = 1; 1715 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1716 } 1717 } 1718 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1719 #if 1 1720 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1721 for (p = 0; p < size; ++p) { 1722 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); 1723 } 1724 #endif 1725 } 1726 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1727 for (f = fStart; f < fMax; ++f) { 1728 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1729 const PetscInt *cone, *support; 1730 PetscInt size, newSize = 2, s; 1731 1732 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1733 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1734 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1735 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1736 for (s = 0; s < size; ++s) { 1737 PetscInt r = 0; 1738 1739 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1740 if (support[s] >= cMax) { 1741 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1742 1743 newSize += 1; 1744 } else { 1745 if (cone[1] == f) r = 1; 1746 else if (cone[2] == f) r = 2; 1747 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1748 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1749 1750 newSize += 2; 1751 } 1752 } 1753 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1754 #if 1 1755 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1756 for (p = 0; p < newSize; ++p) { 1757 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); 1758 } 1759 #endif 1760 } 1761 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1762 break; 1763 case 4: 1764 /* Hybrid Hex 2D */ 1765 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1766 cMax = PetscMin(cEnd, cMax); 1767 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1768 fMax = PetscMin(fEnd, fMax); 1769 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1770 /* Interior cells have 4 faces */ 1771 for (c = cStart; c < cMax; ++c) { 1772 const PetscInt newp = cStartNew + (c - cStart)*4; 1773 const PetscInt *cone, *ornt; 1774 PetscInt coneNew[4], orntNew[4]; 1775 1776 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1777 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1778 /* A quad */ 1779 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1780 orntNew[0] = ornt[0]; 1781 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1782 orntNew[1] = 0; 1783 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1784 orntNew[2] = -2; 1785 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1786 orntNew[3] = ornt[3]; 1787 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1788 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1789 #if 1 1790 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); 1791 for (p = 0; p < 4; ++p) { 1792 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); 1793 } 1794 #endif 1795 /* B quad */ 1796 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1797 orntNew[0] = ornt[0]; 1798 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1799 orntNew[1] = ornt[1]; 1800 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1801 orntNew[2] = 0; 1802 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1803 orntNew[3] = -2; 1804 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1805 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1806 #if 1 1807 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); 1808 for (p = 0; p < 4; ++p) { 1809 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); 1810 } 1811 #endif 1812 /* C quad */ 1813 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1814 orntNew[0] = -2; 1815 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1816 orntNew[1] = ornt[1]; 1817 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1818 orntNew[2] = ornt[2]; 1819 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1820 orntNew[3] = 0; 1821 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1822 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1823 #if 1 1824 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); 1825 for (p = 0; p < 4; ++p) { 1826 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); 1827 } 1828 #endif 1829 /* D quad */ 1830 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1831 orntNew[0] = 0; 1832 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1833 orntNew[1] = -2; 1834 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1835 orntNew[2] = ornt[2]; 1836 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1837 orntNew[3] = ornt[3]; 1838 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1839 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1840 #if 1 1841 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); 1842 for (p = 0; p < 4; ++p) { 1843 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); 1844 } 1845 #endif 1846 } 1847 /* 1848 2----3----3 1849 | | 1850 | B | 1851 | | 1852 0----4--- 1 1853 | | 1854 | A | 1855 | | 1856 0----2----1 1857 */ 1858 /* Hybrid cells have 4 faces */ 1859 for (c = cMax; c < cEnd; ++c) { 1860 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1861 const PetscInt *cone, *ornt; 1862 PetscInt coneNew[4], orntNew[4]; 1863 1864 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1865 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1866 /* A quad */ 1867 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1868 orntNew[0] = ornt[0]; 1869 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1870 orntNew[1] = ornt[1]; 1871 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 1872 orntNew[2] = 0; 1873 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 1874 orntNew[3] = 0; 1875 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1876 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1877 #if 1 1878 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); 1879 for (p = 0; p < 4; ++p) { 1880 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); 1881 } 1882 #endif 1883 /* B quad */ 1884 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1885 orntNew[0] = ornt[0]; 1886 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1887 orntNew[1] = ornt[1]; 1888 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 1889 orntNew[2] = 0; 1890 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 1891 orntNew[3] = 0; 1892 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1893 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1894 #if 1 1895 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); 1896 for (p = 0; p < 4; ++p) { 1897 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); 1898 } 1899 #endif 1900 } 1901 /* Interior split faces have 2 vertices and the same cells as the parent */ 1902 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1903 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1904 for (f = fStart; f < fMax; ++f) { 1905 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1906 1907 for (r = 0; r < 2; ++r) { 1908 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1909 const PetscInt *cone, *ornt, *support; 1910 PetscInt coneNew[2], coneSize, c, supportSize, s; 1911 1912 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1913 coneNew[0] = vStartNew + (cone[0] - vStart); 1914 coneNew[1] = vStartNew + (cone[1] - vStart); 1915 coneNew[(r+1)%2] = newv; 1916 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1917 #if 1 1918 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1919 for (p = 0; p < 2; ++p) { 1920 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); 1921 } 1922 #endif 1923 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1924 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1925 for (s = 0; s < supportSize; ++s) { 1926 if (support[s] >= cMax) { 1927 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 1928 } else { 1929 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1930 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1931 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1932 for (c = 0; c < coneSize; ++c) { 1933 if (cone[c] == f) break; 1934 } 1935 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1936 } 1937 } 1938 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1939 #if 1 1940 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1941 for (p = 0; p < supportSize; ++p) { 1942 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); 1943 } 1944 #endif 1945 } 1946 } 1947 /* Interior cell faces have 2 vertices and 2 cells */ 1948 for (c = cStart; c < cMax; ++c) { 1949 const PetscInt *cone; 1950 1951 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1952 for (r = 0; r < 4; ++r) { 1953 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 1954 PetscInt coneNew[2], supportNew[2]; 1955 1956 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1957 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 1958 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1959 #if 1 1960 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1961 for (p = 0; p < 2; ++p) { 1962 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1963 } 1964 #endif 1965 supportNew[0] = (c - cStart)*4 + r; 1966 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1967 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1968 #if 1 1969 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1970 for (p = 0; p < 2; ++p) { 1971 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); 1972 } 1973 #endif 1974 } 1975 } 1976 /* Hybrid faces have 2 vertices and the same cells */ 1977 for (f = fMax; f < fEnd; ++f) { 1978 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 1979 const PetscInt *cone, *support; 1980 PetscInt coneNew[2], supportNew[2]; 1981 PetscInt size, s, r; 1982 1983 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1984 coneNew[0] = vStartNew + (cone[0] - vStart); 1985 coneNew[1] = vStartNew + (cone[1] - vStart); 1986 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1987 #if 1 1988 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1989 for (p = 0; p < 2; ++p) { 1990 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); 1991 } 1992 #endif 1993 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1994 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1995 for (s = 0; s < size; ++s) { 1996 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1997 for (r = 0; r < 2; ++r) { 1998 if (cone[r+2] == f) break; 1999 } 2000 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2001 } 2002 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2003 #if 1 2004 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2005 for (p = 0; p < size; ++p) { 2006 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); 2007 } 2008 #endif 2009 } 2010 /* Cell hybrid faces have 2 vertices and 2 cells */ 2011 for (c = cMax; c < cEnd; ++c) { 2012 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2013 const PetscInt *cone; 2014 PetscInt coneNew[2], supportNew[2]; 2015 2016 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2017 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2018 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2019 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2020 #if 1 2021 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2022 for (p = 0; p < 2; ++p) { 2023 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); 2024 } 2025 #endif 2026 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2027 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2028 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2029 #if 1 2030 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2031 for (p = 0; p < 2; ++p) { 2032 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); 2033 } 2034 #endif 2035 } 2036 /* Old vertices have identical supports */ 2037 for (v = vStart; v < vEnd; ++v) { 2038 const PetscInt newp = vStartNew + (v - vStart); 2039 const PetscInt *support, *cone; 2040 PetscInt size, s; 2041 2042 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2043 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2044 for (s = 0; s < size; ++s) { 2045 if (support[s] >= fMax) { 2046 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2047 } else { 2048 PetscInt r = 0; 2049 2050 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2051 if (cone[1] == v) r = 1; 2052 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2053 } 2054 } 2055 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2056 #if 1 2057 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2058 for (p = 0; p < size; ++p) { 2059 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); 2060 } 2061 #endif 2062 } 2063 /* Face vertices have 2 + cells supports */ 2064 for (f = fStart; f < fMax; ++f) { 2065 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2066 const PetscInt *cone, *support; 2067 PetscInt size, s; 2068 2069 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2070 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2071 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2072 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2073 for (s = 0; s < size; ++s) { 2074 PetscInt r = 0; 2075 2076 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2077 if (support[s] >= cMax) { 2078 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2079 } else { 2080 if (cone[1] == f) r = 1; 2081 else if (cone[2] == f) r = 2; 2082 else if (cone[3] == f) r = 3; 2083 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2084 } 2085 } 2086 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2087 #if 1 2088 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2089 for (p = 0; p < 2+size; ++p) { 2090 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); 2091 } 2092 #endif 2093 } 2094 /* Cell vertices have 4 supports */ 2095 for (c = cStart; c < cMax; ++c) { 2096 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2097 PetscInt supportNew[4]; 2098 2099 for (r = 0; r < 4; ++r) { 2100 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2101 } 2102 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2103 } 2104 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2105 break; 2106 case 5: 2107 /* Simplicial 3D */ 2108 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2109 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2110 for (c = cStart; c < cEnd; ++c) { 2111 const PetscInt newp = cStartNew + (c - cStart)*8; 2112 const PetscInt *cone, *ornt; 2113 PetscInt coneNew[4], orntNew[4]; 2114 2115 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2116 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2117 /* A tetrahedron: {0, a, c, d} */ 2118 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2119 orntNew[0] = ornt[0]; 2120 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2121 orntNew[1] = ornt[1]; 2122 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2123 orntNew[2] = ornt[2]; 2124 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2125 orntNew[3] = 0; 2126 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2127 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2128 #if 1 2129 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); 2130 for (p = 0; p < 4; ++p) { 2131 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); 2132 } 2133 #endif 2134 /* B tetrahedron: {a, 1, b, e} */ 2135 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2136 orntNew[0] = ornt[0]; 2137 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2138 orntNew[1] = ornt[1]; 2139 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2140 orntNew[2] = 0; 2141 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2142 orntNew[3] = ornt[3]; 2143 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2144 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2145 #if 1 2146 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); 2147 for (p = 0; p < 4; ++p) { 2148 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); 2149 } 2150 #endif 2151 /* C tetrahedron: {c, b, 2, f} */ 2152 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2153 orntNew[0] = ornt[0]; 2154 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2155 orntNew[1] = 0; 2156 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2157 orntNew[2] = ornt[2]; 2158 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2159 orntNew[3] = ornt[3]; 2160 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2161 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2162 #if 1 2163 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); 2164 for (p = 0; p < 4; ++p) { 2165 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); 2166 } 2167 #endif 2168 /* D tetrahedron: {d, e, f, 3} */ 2169 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2170 orntNew[0] = 0; 2171 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2172 orntNew[1] = ornt[1]; 2173 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2174 orntNew[2] = ornt[2]; 2175 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2176 orntNew[3] = ornt[3]; 2177 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2178 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2179 #if 1 2180 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); 2181 for (p = 0; p < 4; ++p) { 2182 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); 2183 } 2184 #endif 2185 /* A' tetrahedron: {d, a, c, f} */ 2186 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2187 orntNew[0] = -3; 2188 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2189 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2190 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2191 orntNew[2] = 0; 2192 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2193 orntNew[3] = 2; 2194 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2195 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2196 #if 1 2197 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); 2198 for (p = 0; p < 4; ++p) { 2199 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); 2200 } 2201 #endif 2202 /* B' tetrahedron: {e, b, a, f} */ 2203 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2204 orntNew[0] = -3; 2205 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2206 orntNew[1] = 1; 2207 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2208 orntNew[2] = 0; 2209 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2210 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2211 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2212 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2213 #if 1 2214 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); 2215 for (p = 0; p < 4; ++p) { 2216 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); 2217 } 2218 #endif 2219 /* C' tetrahedron: {b, f, c, a} */ 2220 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2221 orntNew[0] = -3; 2222 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2223 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2224 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2225 orntNew[2] = -3; 2226 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2227 orntNew[3] = -2; 2228 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2229 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2230 #if 1 2231 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); 2232 for (p = 0; p < 4; ++p) { 2233 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); 2234 } 2235 #endif 2236 /* D' tetrahedron: {f, e, d, a} */ 2237 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2238 orntNew[0] = -3; 2239 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2240 orntNew[1] = -3; 2241 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2242 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2243 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2244 orntNew[3] = -3; 2245 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2246 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2247 #if 1 2248 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); 2249 for (p = 0; p < 4; ++p) { 2250 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); 2251 } 2252 #endif 2253 } 2254 /* Split faces have 3 edges and the same cells as the parent */ 2255 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2256 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2257 for (f = fStart; f < fEnd; ++f) { 2258 const PetscInt newp = fStartNew + (f - fStart)*4; 2259 const PetscInt *cone, *ornt, *support; 2260 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2261 2262 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2263 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2264 /* A triangle */ 2265 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2266 orntNew[0] = ornt[0]; 2267 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2268 orntNew[1] = -2; 2269 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2270 orntNew[2] = ornt[2]; 2271 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2272 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2273 #if 1 2274 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); 2275 for (p = 0; p < 3; ++p) { 2276 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); 2277 } 2278 #endif 2279 /* B triangle */ 2280 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2281 orntNew[0] = ornt[0]; 2282 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2283 orntNew[1] = ornt[1]; 2284 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2285 orntNew[2] = -2; 2286 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2287 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2288 #if 1 2289 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); 2290 for (p = 0; p < 3; ++p) { 2291 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); 2292 } 2293 #endif 2294 /* C triangle */ 2295 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2296 orntNew[0] = -2; 2297 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2298 orntNew[1] = ornt[1]; 2299 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2300 orntNew[2] = ornt[2]; 2301 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2302 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2303 #if 1 2304 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); 2305 for (p = 0; p < 3; ++p) { 2306 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); 2307 } 2308 #endif 2309 /* D triangle */ 2310 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2311 orntNew[0] = 0; 2312 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2313 orntNew[1] = 0; 2314 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2315 orntNew[2] = 0; 2316 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2317 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2318 #if 1 2319 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); 2320 for (p = 0; p < 3; ++p) { 2321 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); 2322 } 2323 #endif 2324 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2325 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2326 for (r = 0; r < 4; ++r) { 2327 for (s = 0; s < supportSize; ++s) { 2328 PetscInt subf; 2329 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2330 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2331 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2332 for (c = 0; c < coneSize; ++c) { 2333 if (cone[c] == f) break; 2334 } 2335 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2336 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2337 } 2338 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2339 #if 1 2340 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); 2341 for (p = 0; p < supportSize; ++p) { 2342 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); 2343 } 2344 #endif 2345 } 2346 } 2347 /* Interior faces have 3 edges and 2 cells */ 2348 for (c = cStart; c < cEnd; ++c) { 2349 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2350 const PetscInt *cone, *ornt; 2351 PetscInt coneNew[3], orntNew[3]; 2352 PetscInt supportNew[2]; 2353 2354 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2355 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2356 /* Face A: {c, a, d} */ 2357 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2358 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2359 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2360 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2361 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2362 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2363 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2364 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2365 #if 1 2366 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2367 for (p = 0; p < 3; ++p) { 2368 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); 2369 } 2370 #endif 2371 supportNew[0] = (c - cStart)*8 + 0; 2372 supportNew[1] = (c - cStart)*8 + 0+4; 2373 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2374 #if 1 2375 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2376 for (p = 0; p < 2; ++p) { 2377 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); 2378 } 2379 #endif 2380 ++newp; 2381 /* Face B: {a, b, e} */ 2382 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2383 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2384 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2385 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2386 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2387 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2388 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2389 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2390 #if 1 2391 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2392 for (p = 0; p < 3; ++p) { 2393 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); 2394 } 2395 #endif 2396 supportNew[0] = (c - cStart)*8 + 1; 2397 supportNew[1] = (c - cStart)*8 + 1+4; 2398 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2399 #if 1 2400 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2401 for (p = 0; p < 2; ++p) { 2402 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); 2403 } 2404 #endif 2405 ++newp; 2406 /* Face C: {c, f, b} */ 2407 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2408 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2409 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2410 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2411 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2412 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2413 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2414 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2415 #if 1 2416 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2417 for (p = 0; p < 3; ++p) { 2418 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); 2419 } 2420 #endif 2421 supportNew[0] = (c - cStart)*8 + 2; 2422 supportNew[1] = (c - cStart)*8 + 2+4; 2423 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2424 #if 1 2425 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2426 for (p = 0; p < 2; ++p) { 2427 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); 2428 } 2429 #endif 2430 ++newp; 2431 /* Face D: {d, e, f} */ 2432 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2433 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2434 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2435 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2436 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2437 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2438 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2439 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2440 #if 1 2441 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2442 for (p = 0; p < 3; ++p) { 2443 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); 2444 } 2445 #endif 2446 supportNew[0] = (c - cStart)*8 + 3; 2447 supportNew[1] = (c - cStart)*8 + 3+4; 2448 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2449 #if 1 2450 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2451 for (p = 0; p < 2; ++p) { 2452 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); 2453 } 2454 #endif 2455 ++newp; 2456 /* Face E: {d, f, a} */ 2457 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2458 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2459 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2460 orntNew[1] = -2; 2461 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2462 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2463 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2464 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2465 #if 1 2466 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2467 for (p = 0; p < 3; ++p) { 2468 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); 2469 } 2470 #endif 2471 supportNew[0] = (c - cStart)*8 + 0+4; 2472 supportNew[1] = (c - cStart)*8 + 3+4; 2473 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2474 #if 1 2475 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2476 for (p = 0; p < 2; ++p) { 2477 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); 2478 } 2479 #endif 2480 ++newp; 2481 /* Face F: {c, a, f} */ 2482 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2483 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2484 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2485 orntNew[1] = 0; 2486 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2487 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2488 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2489 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2490 #if 1 2491 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2492 for (p = 0; p < 3; ++p) { 2493 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); 2494 } 2495 #endif 2496 supportNew[0] = (c - cStart)*8 + 0+4; 2497 supportNew[1] = (c - cStart)*8 + 2+4; 2498 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2499 #if 1 2500 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2501 for (p = 0; p < 2; ++p) { 2502 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); 2503 } 2504 #endif 2505 ++newp; 2506 /* Face G: {e, a, f} */ 2507 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2508 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2509 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2510 orntNew[1] = 0; 2511 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2512 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2513 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2514 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2515 #if 1 2516 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2517 for (p = 0; p < 3; ++p) { 2518 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); 2519 } 2520 #endif 2521 supportNew[0] = (c - cStart)*8 + 1+4; 2522 supportNew[1] = (c - cStart)*8 + 3+4; 2523 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2524 #if 1 2525 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2526 for (p = 0; p < 2; ++p) { 2527 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); 2528 } 2529 #endif 2530 ++newp; 2531 /* Face H: {a, b, f} */ 2532 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2533 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2534 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2535 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2536 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2537 orntNew[2] = -2; 2538 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2539 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2540 #if 1 2541 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2542 for (p = 0; p < 3; ++p) { 2543 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); 2544 } 2545 #endif 2546 supportNew[0] = (c - cStart)*8 + 1+4; 2547 supportNew[1] = (c - cStart)*8 + 2+4; 2548 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2549 #if 1 2550 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2551 for (p = 0; p < 2; ++p) { 2552 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); 2553 } 2554 #endif 2555 ++newp; 2556 } 2557 /* Split Edges have 2 vertices and the same faces as the parent */ 2558 for (e = eStart; e < eEnd; ++e) { 2559 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2560 2561 for (r = 0; r < 2; ++r) { 2562 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2563 const PetscInt *cone, *ornt, *support; 2564 PetscInt coneNew[2], coneSize, c, supportSize, s; 2565 2566 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2567 coneNew[0] = vStartNew + (cone[0] - vStart); 2568 coneNew[1] = vStartNew + (cone[1] - vStart); 2569 coneNew[(r+1)%2] = newv; 2570 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2571 #if 1 2572 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2573 for (p = 0; p < 2; ++p) { 2574 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); 2575 } 2576 #endif 2577 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2578 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2579 for (s = 0; s < supportSize; ++s) { 2580 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2581 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2582 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2583 for (c = 0; c < coneSize; ++c) { 2584 if (cone[c] == e) break; 2585 } 2586 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2587 } 2588 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2589 #if 1 2590 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2591 for (p = 0; p < supportSize; ++p) { 2592 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); 2593 } 2594 #endif 2595 } 2596 } 2597 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2598 for (f = fStart; f < fEnd; ++f) { 2599 const PetscInt *cone, *ornt, *support; 2600 PetscInt coneSize, supportSize, s; 2601 2602 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2603 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2604 for (r = 0; r < 3; ++r) { 2605 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2606 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2607 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2608 -1, -1, 1, 6, 0, 4, 2609 2, 5, 3, 4, -1, -1, 2610 -1, -1, 3, 6, 2, 7}; 2611 2612 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2613 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2614 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2615 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2616 #if 1 2617 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2618 for (p = 0; p < 2; ++p) { 2619 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); 2620 } 2621 #endif 2622 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2623 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2624 for (s = 0; s < supportSize; ++s) { 2625 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2626 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2627 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2628 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2629 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2630 er = GetTetSomethingInverse_Static(ornt[c], r); 2631 if (er == eint[c]) { 2632 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2633 } else { 2634 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2635 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2636 } 2637 } 2638 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2639 #if 1 2640 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2641 for (p = 0; p < intFaces; ++p) { 2642 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); 2643 } 2644 #endif 2645 } 2646 } 2647 /* Interior edges have 2 vertices and 4 faces */ 2648 for (c = cStart; c < cEnd; ++c) { 2649 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2650 const PetscInt *cone, *ornt, *fcone; 2651 PetscInt coneNew[2], supportNew[4], find; 2652 2653 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2654 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2655 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2656 find = GetTriEdge_Static(ornt[0], 0); 2657 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2658 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2659 find = GetTriEdge_Static(ornt[2], 1); 2660 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2661 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2662 #if 1 2663 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2664 for (p = 0; p < 2; ++p) { 2665 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); 2666 } 2667 #endif 2668 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2669 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2670 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2671 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2672 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2673 #if 1 2674 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2675 for (p = 0; p < 4; ++p) { 2676 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); 2677 } 2678 #endif 2679 } 2680 /* Old vertices have identical supports */ 2681 for (v = vStart; v < vEnd; ++v) { 2682 const PetscInt newp = vStartNew + (v - vStart); 2683 const PetscInt *support, *cone; 2684 PetscInt size, s; 2685 2686 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2687 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2688 for (s = 0; s < size; ++s) { 2689 PetscInt r = 0; 2690 2691 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2692 if (cone[1] == v) r = 1; 2693 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2694 } 2695 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2696 #if 1 2697 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2698 for (p = 0; p < size; ++p) { 2699 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); 2700 } 2701 #endif 2702 } 2703 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2704 for (e = eStart; e < eEnd; ++e) { 2705 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2706 const PetscInt *cone, *support; 2707 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2708 2709 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2710 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2711 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2712 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2713 for (s = 0; s < size; ++s) { 2714 PetscInt r = 0; 2715 2716 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2717 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2718 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2719 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2720 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2721 } 2722 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2723 for (s = 0; s < starSize*2; s += 2) { 2724 const PetscInt *cone, *ornt; 2725 PetscInt e01, e23; 2726 2727 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2728 /* Check edge 0-1 */ 2729 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2730 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2731 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2732 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2733 /* Check edge 2-3 */ 2734 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2735 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2736 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2737 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2738 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2739 } 2740 } 2741 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2742 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2743 #if 1 2744 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2745 for (p = 0; p < 2+size*2+cellSize; ++p) { 2746 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); 2747 } 2748 #endif 2749 } 2750 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2751 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2752 break; 2753 case 7: 2754 /* Hybrid Simplicial 3D */ 2755 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2756 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2757 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2758 for (c = cStart; c < cMax; ++c) { 2759 const PetscInt newp = cStartNew + (c - cStart)*8; 2760 const PetscInt *cone, *ornt; 2761 PetscInt coneNew[4], orntNew[4]; 2762 2763 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2764 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2765 /* A tetrahedron: {0, a, c, d} */ 2766 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2767 orntNew[0] = ornt[0]; 2768 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2769 orntNew[1] = ornt[1]; 2770 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2771 orntNew[2] = ornt[2]; 2772 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2773 orntNew[3] = 0; 2774 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2775 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2776 #if 1 2777 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); 2778 for (p = 0; p < 4; ++p) { 2779 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); 2780 } 2781 #endif 2782 /* B tetrahedron: {a, 1, b, e} */ 2783 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2784 orntNew[0] = ornt[0]; 2785 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2786 orntNew[1] = ornt[1]; 2787 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2788 orntNew[2] = 0; 2789 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2790 orntNew[3] = ornt[3]; 2791 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2792 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2793 #if 1 2794 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); 2795 for (p = 0; p < 4; ++p) { 2796 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); 2797 } 2798 #endif 2799 /* C tetrahedron: {c, b, 2, f} */ 2800 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2801 orntNew[0] = ornt[0]; 2802 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2803 orntNew[1] = 0; 2804 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2805 orntNew[2] = ornt[2]; 2806 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2807 orntNew[3] = ornt[3]; 2808 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2809 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2810 #if 1 2811 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); 2812 for (p = 0; p < 4; ++p) { 2813 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); 2814 } 2815 #endif 2816 /* D tetrahedron: {d, e, f, 3} */ 2817 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2818 orntNew[0] = 0; 2819 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2820 orntNew[1] = ornt[1]; 2821 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2822 orntNew[2] = ornt[2]; 2823 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2824 orntNew[3] = ornt[3]; 2825 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2826 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2827 #if 1 2828 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); 2829 for (p = 0; p < 4; ++p) { 2830 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); 2831 } 2832 #endif 2833 /* A' tetrahedron: {d, a, c, f} */ 2834 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2835 orntNew[0] = -3; 2836 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2837 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2838 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2839 orntNew[2] = 0; 2840 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2841 orntNew[3] = 2; 2842 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2843 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2844 #if 1 2845 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); 2846 for (p = 0; p < 4; ++p) { 2847 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); 2848 } 2849 #endif 2850 /* B' tetrahedron: {e, b, a, f} */ 2851 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2852 orntNew[0] = -3; 2853 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2854 orntNew[1] = 1; 2855 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2856 orntNew[2] = 0; 2857 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2858 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2859 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2860 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2861 #if 1 2862 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); 2863 for (p = 0; p < 4; ++p) { 2864 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); 2865 } 2866 #endif 2867 /* C' tetrahedron: {b, f, c, a} */ 2868 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2869 orntNew[0] = -3; 2870 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2871 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2872 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2873 orntNew[2] = -3; 2874 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2875 orntNew[3] = -2; 2876 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2877 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2878 #if 1 2879 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); 2880 for (p = 0; p < 4; ++p) { 2881 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); 2882 } 2883 #endif 2884 /* D' tetrahedron: {f, e, d, a} */ 2885 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2886 orntNew[0] = -3; 2887 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2888 orntNew[1] = -3; 2889 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2890 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2891 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2892 orntNew[3] = -3; 2893 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2894 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2895 #if 1 2896 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); 2897 for (p = 0; p < 4; ++p) { 2898 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); 2899 } 2900 #endif 2901 } 2902 /* Hybrid cells have 5 faces */ 2903 for (c = cMax; c < cEnd; ++c) { 2904 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 2905 const PetscInt *cone, *ornt, *fornt; 2906 PetscInt coneNew[5], orntNew[5], o, of, i; 2907 2908 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2909 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2910 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 2911 o = ornt[0] < 0 ? -1 : 1; 2912 for (r = 0; r < 3; ++r) { 2913 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 2914 orntNew[0] = ornt[0]; 2915 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 2916 orntNew[1] = ornt[1]; 2917 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 2918 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 2919 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 2920 orntNew[i] = 0; 2921 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 2922 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 2923 orntNew[i] = 0; 2924 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 2925 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 2926 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); 2927 orntNew[i] = 0; 2928 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2929 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2930 #if 1 2931 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); 2932 for (p = 0; p < 2; ++p) { 2933 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); 2934 } 2935 for (p = 2; p < 5; ++p) { 2936 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); 2937 } 2938 #endif 2939 } 2940 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 2941 orntNew[0] = 0; 2942 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 2943 orntNew[1] = 0; 2944 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 2945 orntNew[2] = 0; 2946 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 2947 orntNew[3] = 0; 2948 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 2949 orntNew[4] = 0; 2950 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2951 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2952 #if 1 2953 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); 2954 for (p = 0; p < 2; ++p) { 2955 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); 2956 } 2957 for (p = 2; p < 5; ++p) { 2958 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); 2959 } 2960 #endif 2961 } 2962 /* Split faces have 3 edges and the same cells as the parent */ 2963 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2964 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2965 for (f = fStart; f < fMax; ++f) { 2966 const PetscInt newp = fStartNew + (f - fStart)*4; 2967 const PetscInt *cone, *ornt, *support; 2968 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2969 2970 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2971 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2972 /* A triangle */ 2973 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2974 orntNew[0] = ornt[0]; 2975 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2976 orntNew[1] = -2; 2977 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2978 orntNew[2] = ornt[2]; 2979 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2980 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2981 #if 1 2982 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); 2983 for (p = 0; p < 3; ++p) { 2984 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); 2985 } 2986 #endif 2987 /* B triangle */ 2988 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2989 orntNew[0] = ornt[0]; 2990 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2991 orntNew[1] = ornt[1]; 2992 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2993 orntNew[2] = -2; 2994 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2995 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2996 #if 1 2997 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); 2998 for (p = 0; p < 3; ++p) { 2999 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); 3000 } 3001 #endif 3002 /* C triangle */ 3003 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3004 orntNew[0] = -2; 3005 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3006 orntNew[1] = ornt[1]; 3007 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3008 orntNew[2] = ornt[2]; 3009 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3010 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3011 #if 1 3012 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); 3013 for (p = 0; p < 3; ++p) { 3014 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); 3015 } 3016 #endif 3017 /* D triangle */ 3018 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3019 orntNew[0] = 0; 3020 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3021 orntNew[1] = 0; 3022 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3023 orntNew[2] = 0; 3024 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3025 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3026 #if 1 3027 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); 3028 for (p = 0; p < 3; ++p) { 3029 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); 3030 } 3031 #endif 3032 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3033 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3034 for (r = 0; r < 4; ++r) { 3035 for (s = 0; s < supportSize; ++s) { 3036 PetscInt subf; 3037 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3038 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3039 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3040 for (c = 0; c < coneSize; ++c) { 3041 if (cone[c] == f) break; 3042 } 3043 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3044 if (support[s] < cMax) { 3045 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3046 } else { 3047 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3048 } 3049 } 3050 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3051 #if 1 3052 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); 3053 for (p = 0; p < supportSize; ++p) { 3054 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); 3055 } 3056 #endif 3057 } 3058 } 3059 /* Interior cell faces have 3 edges and 2 cells */ 3060 for (c = cStart; c < cMax; ++c) { 3061 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3062 const PetscInt *cone, *ornt; 3063 PetscInt coneNew[3], orntNew[3]; 3064 PetscInt supportNew[2]; 3065 3066 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3067 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3068 /* Face A: {c, a, d} */ 3069 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3070 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3071 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3072 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3073 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 3074 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3075 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3076 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3077 #if 1 3078 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3079 for (p = 0; p < 3; ++p) { 3080 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); 3081 } 3082 #endif 3083 supportNew[0] = (c - cStart)*8 + 0; 3084 supportNew[1] = (c - cStart)*8 + 0+4; 3085 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3086 #if 1 3087 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3088 for (p = 0; p < 2; ++p) { 3089 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); 3090 } 3091 #endif 3092 ++newp; 3093 /* Face B: {a, b, e} */ 3094 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3095 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3096 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 3097 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3098 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3099 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3100 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3101 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3102 #if 1 3103 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); 3104 for (p = 0; p < 3; ++p) { 3105 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); 3106 } 3107 #endif 3108 supportNew[0] = (c - cStart)*8 + 1; 3109 supportNew[1] = (c - cStart)*8 + 1+4; 3110 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3111 #if 1 3112 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3113 for (p = 0; p < 2; ++p) { 3114 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); 3115 } 3116 #endif 3117 ++newp; 3118 /* Face C: {c, f, b} */ 3119 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3120 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3121 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3122 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3123 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 3124 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3125 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3126 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3127 #if 1 3128 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3129 for (p = 0; p < 3; ++p) { 3130 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); 3131 } 3132 #endif 3133 supportNew[0] = (c - cStart)*8 + 2; 3134 supportNew[1] = (c - cStart)*8 + 2+4; 3135 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3136 #if 1 3137 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3138 for (p = 0; p < 2; ++p) { 3139 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); 3140 } 3141 #endif 3142 ++newp; 3143 /* Face D: {d, e, f} */ 3144 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 3145 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3146 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3147 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3148 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3149 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3150 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3151 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3152 #if 1 3153 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3154 for (p = 0; p < 3; ++p) { 3155 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); 3156 } 3157 #endif 3158 supportNew[0] = (c - cStart)*8 + 3; 3159 supportNew[1] = (c - cStart)*8 + 3+4; 3160 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3161 #if 1 3162 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3163 for (p = 0; p < 2; ++p) { 3164 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); 3165 } 3166 #endif 3167 ++newp; 3168 /* Face E: {d, f, a} */ 3169 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3170 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3171 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3172 orntNew[1] = -2; 3173 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3174 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3175 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3176 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3177 #if 1 3178 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3179 for (p = 0; p < 3; ++p) { 3180 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); 3181 } 3182 #endif 3183 supportNew[0] = (c - cStart)*8 + 0+4; 3184 supportNew[1] = (c - cStart)*8 + 3+4; 3185 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3186 #if 1 3187 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3188 for (p = 0; p < 2; ++p) { 3189 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); 3190 } 3191 #endif 3192 ++newp; 3193 /* Face F: {c, a, f} */ 3194 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3195 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3196 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3197 orntNew[1] = 0; 3198 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3199 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3200 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3201 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3202 #if 1 3203 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3204 for (p = 0; p < 3; ++p) { 3205 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); 3206 } 3207 #endif 3208 supportNew[0] = (c - cStart)*8 + 0+4; 3209 supportNew[1] = (c - cStart)*8 + 2+4; 3210 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3211 #if 1 3212 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3213 for (p = 0; p < 2; ++p) { 3214 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); 3215 } 3216 #endif 3217 ++newp; 3218 /* Face G: {e, a, f} */ 3219 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3220 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3221 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3222 orntNew[1] = 0; 3223 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3224 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3225 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3226 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3227 #if 1 3228 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3229 for (p = 0; p < 3; ++p) { 3230 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); 3231 } 3232 #endif 3233 supportNew[0] = (c - cStart)*8 + 1+4; 3234 supportNew[1] = (c - cStart)*8 + 3+4; 3235 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3236 #if 1 3237 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3238 for (p = 0; p < 2; ++p) { 3239 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); 3240 } 3241 #endif 3242 ++newp; 3243 /* Face H: {a, b, f} */ 3244 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3245 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3246 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3247 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3248 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3249 orntNew[2] = -2; 3250 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3251 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3252 #if 1 3253 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3254 for (p = 0; p < 3; ++p) { 3255 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); 3256 } 3257 #endif 3258 supportNew[0] = (c - cStart)*8 + 1+4; 3259 supportNew[1] = (c - cStart)*8 + 2+4; 3260 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3261 #if 1 3262 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3263 for (p = 0; p < 2; ++p) { 3264 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); 3265 } 3266 #endif 3267 ++newp; 3268 } 3269 /* Hybrid split faces have 4 edges and same cells */ 3270 for (f = fMax; f < fEnd; ++f) { 3271 const PetscInt *cone, *ornt, *support; 3272 PetscInt coneNew[4], orntNew[4]; 3273 PetscInt supportNew[2], size, s, c; 3274 3275 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3276 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3277 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3278 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3279 for (r = 0; r < 2; ++r) { 3280 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3281 3282 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3283 orntNew[0] = ornt[0]; 3284 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3285 orntNew[1] = ornt[1]; 3286 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3287 orntNew[2+r] = 0; 3288 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3289 orntNew[3-r] = 0; 3290 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3291 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3292 #if 1 3293 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3294 for (p = 0; p < 2; ++p) { 3295 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); 3296 } 3297 for (p = 2; p < 4; ++p) { 3298 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); 3299 } 3300 #endif 3301 for (s = 0; s < size; ++s) { 3302 const PetscInt *coneCell, *orntCell, *fornt; 3303 PetscInt o, of; 3304 3305 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3306 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3307 o = orntCell[0] < 0 ? -1 : 1; 3308 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3309 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3310 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3311 of = fornt[c-2] < 0 ? -1 : 1; 3312 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3313 } 3314 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3315 #if 1 3316 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3317 for (p = 0; p < size; ++p) { 3318 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); 3319 } 3320 #endif 3321 } 3322 } 3323 /* Hybrid cell faces have 4 edges and 2 cells */ 3324 for (c = cMax; c < cEnd; ++c) { 3325 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3326 const PetscInt *cone, *ornt; 3327 PetscInt coneNew[4], orntNew[4]; 3328 PetscInt supportNew[2]; 3329 3330 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3331 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3332 for (r = 0; r < 3; ++r) { 3333 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3334 orntNew[0] = 0; 3335 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3336 orntNew[1] = 0; 3337 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3338 orntNew[2] = 0; 3339 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3340 orntNew[3] = 0; 3341 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3342 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3343 #if 1 3344 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); 3345 for (p = 0; p < 2; ++p) { 3346 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); 3347 } 3348 for (p = 2; p < 4; ++p) { 3349 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); 3350 } 3351 #endif 3352 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3353 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3354 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3355 #if 1 3356 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); 3357 for (p = 0; p < 2; ++p) { 3358 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); 3359 } 3360 #endif 3361 } 3362 } 3363 /* Interior split edges have 2 vertices and the same faces as the parent */ 3364 for (e = eStart; e < eMax; ++e) { 3365 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3366 3367 for (r = 0; r < 2; ++r) { 3368 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3369 const PetscInt *cone, *ornt, *support; 3370 PetscInt coneNew[2], coneSize, c, supportSize, s; 3371 3372 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3373 coneNew[0] = vStartNew + (cone[0] - vStart); 3374 coneNew[1] = vStartNew + (cone[1] - vStart); 3375 coneNew[(r+1)%2] = newv; 3376 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3377 #if 1 3378 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3379 for (p = 0; p < 2; ++p) { 3380 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); 3381 } 3382 #endif 3383 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3384 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3385 for (s = 0; s < supportSize; ++s) { 3386 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3387 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3388 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3389 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3390 if (support[s] < fMax) { 3391 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3392 } else { 3393 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3394 } 3395 } 3396 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3397 #if 1 3398 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3399 for (p = 0; p < supportSize; ++p) { 3400 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); 3401 } 3402 #endif 3403 } 3404 } 3405 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3406 for (f = fStart; f < fMax; ++f) { 3407 const PetscInt *cone, *ornt, *support; 3408 PetscInt coneSize, supportSize, s; 3409 3410 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3411 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3412 for (r = 0; r < 3; ++r) { 3413 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3414 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3415 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3416 -1, -1, 1, 6, 0, 4, 3417 2, 5, 3, 4, -1, -1, 3418 -1, -1, 3, 6, 2, 7}; 3419 3420 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3421 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3422 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3423 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3424 #if 1 3425 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3426 for (p = 0; p < 2; ++p) { 3427 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); 3428 } 3429 #endif 3430 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3431 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3432 for (s = 0; s < supportSize; ++s) { 3433 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3434 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3435 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3436 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3437 if (support[s] < cMax) { 3438 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3439 er = GetTetSomethingInverse_Static(ornt[c], r); 3440 if (er == eint[c]) { 3441 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3442 } else { 3443 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3444 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3445 } 3446 } else { 3447 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 3448 } 3449 } 3450 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3451 #if 1 3452 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3453 for (p = 0; p < intFaces; ++p) { 3454 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); 3455 } 3456 #endif 3457 } 3458 } 3459 /* Interior cell edges have 2 vertices and 4 faces */ 3460 for (c = cStart; c < cMax; ++c) { 3461 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3462 const PetscInt *cone, *ornt, *fcone; 3463 PetscInt coneNew[2], supportNew[4], find; 3464 3465 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3466 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3467 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3468 find = GetTriEdge_Static(ornt[0], 0); 3469 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3470 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3471 find = GetTriEdge_Static(ornt[2], 1); 3472 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3473 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3474 #if 1 3475 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3476 for (p = 0; p < 2; ++p) { 3477 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); 3478 } 3479 #endif 3480 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3481 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3482 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3483 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3484 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3485 #if 1 3486 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3487 for (p = 0; p < 4; ++p) { 3488 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); 3489 } 3490 #endif 3491 } 3492 /* Hybrid edges have two vertices and the same faces */ 3493 for (e = eMax; e < eEnd; ++e) { 3494 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3495 const PetscInt *cone, *support, *fcone; 3496 PetscInt coneNew[2], size, fsize, s; 3497 3498 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3499 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3500 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3501 coneNew[0] = vStartNew + (cone[0] - vStart); 3502 coneNew[1] = vStartNew + (cone[1] - vStart); 3503 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3504 #if 1 3505 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3506 for (p = 0; p < 2; ++p) { 3507 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); 3508 } 3509 #endif 3510 for (s = 0; s < size; ++s) { 3511 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3512 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3513 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3514 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3515 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3516 } 3517 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3518 #if 1 3519 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3520 for (p = 0; p < size; ++p) { 3521 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); 3522 } 3523 #endif 3524 } 3525 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3526 for (f = fMax; f < fEnd; ++f) { 3527 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3528 const PetscInt *cone, *support, *ccone, *cornt; 3529 PetscInt coneNew[2], size, csize, s; 3530 3531 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3532 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3533 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3534 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3535 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3536 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3537 #if 1 3538 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3539 for (p = 0; p < 2; ++p) { 3540 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); 3541 } 3542 #endif 3543 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3544 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3545 for (s = 0; s < size; ++s) { 3546 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3547 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3548 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3549 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3550 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]); 3551 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 3552 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 3553 } 3554 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3555 #if 1 3556 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3557 for (p = 0; p < 2+size*2; ++p) { 3558 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); 3559 } 3560 #endif 3561 } 3562 /* Interior vertices have identical supports */ 3563 for (v = vStart; v < vEnd; ++v) { 3564 const PetscInt newp = vStartNew + (v - vStart); 3565 const PetscInt *support, *cone; 3566 PetscInt size, s; 3567 3568 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3569 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3570 for (s = 0; s < size; ++s) { 3571 PetscInt r = 0; 3572 3573 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3574 if (cone[1] == v) r = 1; 3575 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3576 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3577 } 3578 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3579 #if 1 3580 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3581 for (p = 0; p < size; ++p) { 3582 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); 3583 } 3584 #endif 3585 } 3586 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3587 for (e = eStart; e < eMax; ++e) { 3588 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3589 const PetscInt *cone, *support; 3590 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3591 3592 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3593 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3594 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3595 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3596 for (s = 0; s < size; ++s) { 3597 PetscInt r = 0; 3598 3599 if (support[s] < fMax) { 3600 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3601 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3602 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3603 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3604 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3605 faceSize += 2; 3606 } else { 3607 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3608 ++faceSize; 3609 } 3610 } 3611 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3612 for (s = 0; s < starSize*2; s += 2) { 3613 const PetscInt *cone, *ornt; 3614 PetscInt e01, e23; 3615 3616 if ((star[s] >= cStart) && (star[s] < cMax)) { 3617 /* Check edge 0-1 */ 3618 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3619 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3620 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3621 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3622 /* Check edge 2-3 */ 3623 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3624 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3625 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3626 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3627 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3628 } 3629 } 3630 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3631 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3632 #if 1 3633 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3634 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3635 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); 3636 } 3637 #endif 3638 } 3639 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3640 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3641 break; 3642 case 6: 3643 /* Hex 3D */ 3644 /* 3645 Bottom (viewed from top) Top 3646 1---------2---------2 7---------2---------6 3647 | | | | | | 3648 | B 2 C | | H 2 G | 3649 | | | | | | 3650 3----3----0----1----1 3----3----0----1----1 3651 | | | | | | 3652 | A 0 D | | E 0 F | 3653 | | | | | | 3654 0---------0---------3 4---------0---------5 3655 */ 3656 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3657 for (c = cStart; c < cEnd; ++c) { 3658 const PetscInt newp = (c - cStart)*8; 3659 const PetscInt *cone, *ornt; 3660 PetscInt coneNew[6], orntNew[6]; 3661 3662 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3663 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3664 /* A hex */ 3665 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3666 orntNew[0] = ornt[0]; 3667 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3668 orntNew[1] = 0; 3669 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3670 orntNew[2] = ornt[2]; 3671 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3672 orntNew[3] = 0; 3673 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3674 orntNew[4] = 0; 3675 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3676 orntNew[5] = ornt[5]; 3677 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3678 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3679 #if 1 3680 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); 3681 for (p = 0; p < 6; ++p) { 3682 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); 3683 } 3684 #endif 3685 /* B hex */ 3686 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3687 orntNew[0] = ornt[0]; 3688 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3689 orntNew[1] = 0; 3690 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3691 orntNew[2] = -1; 3692 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3693 orntNew[3] = ornt[3]; 3694 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3695 orntNew[4] = 0; 3696 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3697 orntNew[5] = ornt[5]; 3698 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3699 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3700 #if 1 3701 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); 3702 for (p = 0; p < 6; ++p) { 3703 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); 3704 } 3705 #endif 3706 /* C hex */ 3707 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3708 orntNew[0] = ornt[0]; 3709 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3710 orntNew[1] = 0; 3711 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3712 orntNew[2] = -1; 3713 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3714 orntNew[3] = ornt[3]; 3715 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3716 orntNew[4] = ornt[4]; 3717 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3718 orntNew[5] = -4; 3719 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3720 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3721 #if 1 3722 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); 3723 for (p = 0; p < 6; ++p) { 3724 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); 3725 } 3726 #endif 3727 /* D hex */ 3728 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3729 orntNew[0] = ornt[0]; 3730 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3731 orntNew[1] = 0; 3732 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3733 orntNew[2] = ornt[2]; 3734 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3735 orntNew[3] = 0; 3736 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3737 orntNew[4] = ornt[4]; 3738 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3739 orntNew[5] = -4; 3740 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3741 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3742 #if 1 3743 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); 3744 for (p = 0; p < 6; ++p) { 3745 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); 3746 } 3747 #endif 3748 /* E hex */ 3749 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3750 orntNew[0] = -4; 3751 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3752 orntNew[1] = ornt[1]; 3753 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3754 orntNew[2] = ornt[2]; 3755 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3756 orntNew[3] = 0; 3757 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3758 orntNew[4] = -1; 3759 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3760 orntNew[5] = ornt[5]; 3761 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3762 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3763 #if 1 3764 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); 3765 for (p = 0; p < 6; ++p) { 3766 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); 3767 } 3768 #endif 3769 /* F hex */ 3770 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3771 orntNew[0] = -4; 3772 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3773 orntNew[1] = ornt[1]; 3774 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3775 orntNew[2] = ornt[2]; 3776 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3777 orntNew[3] = -1; 3778 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3779 orntNew[4] = ornt[4]; 3780 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3781 orntNew[5] = 1; 3782 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3783 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3784 #if 1 3785 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); 3786 for (p = 0; p < 6; ++p) { 3787 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); 3788 } 3789 #endif 3790 /* G hex */ 3791 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3792 orntNew[0] = -4; 3793 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3794 orntNew[1] = ornt[1]; 3795 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3796 orntNew[2] = 0; 3797 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3798 orntNew[3] = ornt[3]; 3799 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3800 orntNew[4] = ornt[4]; 3801 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3802 orntNew[5] = -3; 3803 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3804 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3805 #if 1 3806 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); 3807 for (p = 0; p < 6; ++p) { 3808 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); 3809 } 3810 #endif 3811 /* H hex */ 3812 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3813 orntNew[0] = -4; 3814 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3815 orntNew[1] = ornt[1]; 3816 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3817 orntNew[2] = -1; 3818 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3819 orntNew[3] = ornt[3]; 3820 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3821 orntNew[4] = 3; 3822 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3823 orntNew[5] = ornt[5]; 3824 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3825 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3826 #if 1 3827 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); 3828 for (p = 0; p < 6; ++p) { 3829 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); 3830 } 3831 #endif 3832 } 3833 /* Split faces have 4 edges and the same cells as the parent */ 3834 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3835 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3836 for (f = fStart; f < fEnd; ++f) { 3837 for (r = 0; r < 4; ++r) { 3838 /* TODO: This can come from GetFaces_Internal() */ 3839 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}; 3840 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3841 const PetscInt *cone, *ornt, *support; 3842 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3843 3844 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3845 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3846 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3847 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3848 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3849 orntNew[(r+0)%4] = ornt[r]; 3850 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3851 orntNew[(r+1)%4] = 0; 3852 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3853 orntNew[(r+2)%4] = -2; 3854 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3855 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3856 #if 1 3857 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3858 for (p = 0; p < 4; ++p) { 3859 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); 3860 } 3861 #endif 3862 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3863 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3864 for (s = 0; s < supportSize; ++s) { 3865 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3866 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3867 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3868 for (c = 0; c < coneSize; ++c) { 3869 if (cone[c] == f) break; 3870 } 3871 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 3872 } 3873 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3874 #if 1 3875 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3876 for (p = 0; p < supportSize; ++p) { 3877 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); 3878 } 3879 #endif 3880 } 3881 } 3882 /* Interior faces have 4 edges and 2 cells */ 3883 for (c = cStart; c < cEnd; ++c) { 3884 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}; 3885 const PetscInt *cone, *ornt; 3886 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3887 3888 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3889 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3890 /* A-D face */ 3891 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3892 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3893 orntNew[0] = 0; 3894 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3895 orntNew[1] = 0; 3896 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3897 orntNew[2] = -2; 3898 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3899 orntNew[3] = -2; 3900 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3901 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3902 #if 1 3903 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3904 for (p = 0; p < 4; ++p) { 3905 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); 3906 } 3907 #endif 3908 /* C-D face */ 3909 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3910 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3911 orntNew[0] = 0; 3912 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3913 orntNew[1] = 0; 3914 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3915 orntNew[2] = -2; 3916 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3917 orntNew[3] = -2; 3918 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3919 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3920 #if 1 3921 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3922 for (p = 0; p < 4; ++p) { 3923 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); 3924 } 3925 #endif 3926 /* B-C face */ 3927 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3928 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3929 orntNew[0] = -2; 3930 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3931 orntNew[1] = 0; 3932 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3933 orntNew[2] = 0; 3934 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3935 orntNew[3] = -2; 3936 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3937 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3938 #if 1 3939 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3940 for (p = 0; p < 4; ++p) { 3941 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); 3942 } 3943 #endif 3944 /* A-B face */ 3945 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3946 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3947 orntNew[0] = -2; 3948 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3949 orntNew[1] = 0; 3950 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3951 orntNew[2] = 0; 3952 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3953 orntNew[3] = -2; 3954 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3955 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3956 #if 1 3957 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3958 for (p = 0; p < 4; ++p) { 3959 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); 3960 } 3961 #endif 3962 /* E-F face */ 3963 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3964 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3965 orntNew[0] = -2; 3966 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3967 orntNew[1] = -2; 3968 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3969 orntNew[2] = 0; 3970 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3971 orntNew[3] = 0; 3972 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3973 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3974 #if 1 3975 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3976 for (p = 0; p < 4; ++p) { 3977 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); 3978 } 3979 #endif 3980 /* F-G face */ 3981 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3982 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3983 orntNew[0] = -2; 3984 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3985 orntNew[1] = -2; 3986 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3987 orntNew[2] = 0; 3988 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3989 orntNew[3] = 0; 3990 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3991 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3992 #if 1 3993 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3994 for (p = 0; p < 4; ++p) { 3995 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); 3996 } 3997 #endif 3998 /* G-H face */ 3999 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 4000 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4001 orntNew[0] = -2; 4002 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4003 orntNew[1] = 0; 4004 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4005 orntNew[2] = 0; 4006 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4007 orntNew[3] = -2; 4008 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4009 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4010 #if 1 4011 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4012 for (p = 0; p < 4; ++p) { 4013 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); 4014 } 4015 #endif 4016 /* E-H face */ 4017 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 4018 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4019 orntNew[0] = -2; 4020 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4021 orntNew[1] = -2; 4022 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4023 orntNew[2] = 0; 4024 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4025 orntNew[3] = 0; 4026 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4027 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4028 #if 1 4029 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4030 for (p = 0; p < 4; ++p) { 4031 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); 4032 } 4033 #endif 4034 /* A-E face */ 4035 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 4036 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4037 orntNew[0] = 0; 4038 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4039 orntNew[1] = 0; 4040 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4041 orntNew[2] = -2; 4042 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4043 orntNew[3] = -2; 4044 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4045 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4046 #if 1 4047 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4048 for (p = 0; p < 4; ++p) { 4049 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); 4050 } 4051 #endif 4052 /* D-F face */ 4053 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 4054 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4055 orntNew[0] = -2; 4056 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4057 orntNew[1] = 0; 4058 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4059 orntNew[2] = 0; 4060 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4061 orntNew[3] = -2; 4062 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4063 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4064 #if 1 4065 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4066 for (p = 0; p < 4; ++p) { 4067 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); 4068 } 4069 #endif 4070 /* C-G face */ 4071 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 4072 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4073 orntNew[0] = -2; 4074 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4075 orntNew[1] = -2; 4076 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4077 orntNew[2] = 0; 4078 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4079 orntNew[3] = 0; 4080 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4081 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4082 #if 1 4083 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4084 for (p = 0; p < 4; ++p) { 4085 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); 4086 } 4087 #endif 4088 /* B-H face */ 4089 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 4090 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4091 orntNew[0] = 0; 4092 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4093 orntNew[1] = -2; 4094 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4095 orntNew[2] = -2; 4096 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4097 orntNew[3] = 0; 4098 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4099 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4100 #if 1 4101 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4102 for (p = 0; p < 4; ++p) { 4103 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); 4104 } 4105 #endif 4106 for (r = 0; r < 12; ++r) { 4107 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 4108 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4109 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4110 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4111 #if 1 4112 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4113 for (p = 0; p < 2; ++p) { 4114 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); 4115 } 4116 #endif 4117 } 4118 } 4119 /* Split edges have 2 vertices and the same faces as the parent */ 4120 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4121 for (e = eStart; e < eEnd; ++e) { 4122 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4123 4124 for (r = 0; r < 2; ++r) { 4125 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4126 const PetscInt *cone, *ornt, *support; 4127 PetscInt coneNew[2], coneSize, c, supportSize, s; 4128 4129 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4130 coneNew[0] = vStartNew + (cone[0] - vStart); 4131 coneNew[1] = vStartNew + (cone[1] - vStart); 4132 coneNew[(r+1)%2] = newv; 4133 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4134 #if 1 4135 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4136 for (p = 0; p < 2; ++p) { 4137 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); 4138 } 4139 #endif 4140 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4141 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4142 for (s = 0; s < supportSize; ++s) { 4143 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4144 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4145 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4146 for (c = 0; c < coneSize; ++c) { 4147 if (cone[c] == e) break; 4148 } 4149 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 4150 } 4151 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4152 #if 1 4153 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4154 for (p = 0; p < supportSize; ++p) { 4155 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); 4156 } 4157 #endif 4158 } 4159 } 4160 /* Face edges have 2 vertices and 2+cells faces */ 4161 for (f = fStart; f < fEnd; ++f) { 4162 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}; 4163 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4164 const PetscInt *cone, *coneCell, *orntCell, *support; 4165 PetscInt coneNew[2], coneSize, c, supportSize, s; 4166 4167 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4168 for (r = 0; r < 4; ++r) { 4169 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4170 4171 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4172 coneNew[1] = newv; 4173 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4174 #if 1 4175 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4176 for (p = 0; p < 2; ++p) { 4177 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); 4178 } 4179 #endif 4180 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4181 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4182 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4183 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4184 for (s = 0; s < supportSize; ++s) { 4185 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4186 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4187 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4188 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4189 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4190 } 4191 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4192 #if 1 4193 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4194 for (p = 0; p < 2+supportSize; ++p) { 4195 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); 4196 } 4197 #endif 4198 } 4199 } 4200 /* Cell edges have 2 vertices and 4 faces */ 4201 for (c = cStart; c < cEnd; ++c) { 4202 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}; 4203 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4204 const PetscInt *cone; 4205 PetscInt coneNew[2], supportNew[4]; 4206 4207 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4208 for (r = 0; r < 6; ++r) { 4209 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4210 4211 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4212 coneNew[1] = newv; 4213 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4214 #if 1 4215 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4216 for (p = 0; p < 2; ++p) { 4217 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); 4218 } 4219 #endif 4220 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4221 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4222 #if 1 4223 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4224 for (p = 0; p < 4; ++p) { 4225 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); 4226 } 4227 #endif 4228 } 4229 } 4230 /* Old vertices have identical supports */ 4231 for (v = vStart; v < vEnd; ++v) { 4232 const PetscInt newp = vStartNew + (v - vStart); 4233 const PetscInt *support, *cone; 4234 PetscInt size, s; 4235 4236 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4237 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4238 for (s = 0; s < size; ++s) { 4239 PetscInt r = 0; 4240 4241 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4242 if (cone[1] == v) r = 1; 4243 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4244 } 4245 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4246 #if 1 4247 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4248 for (p = 0; p < size; ++p) { 4249 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); 4250 } 4251 #endif 4252 } 4253 /* Edge vertices have 2 + faces supports */ 4254 for (e = eStart; e < eEnd; ++e) { 4255 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4256 const PetscInt *cone, *support; 4257 PetscInt size, s; 4258 4259 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4260 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4261 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4262 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4263 for (s = 0; s < size; ++s) { 4264 PetscInt r; 4265 4266 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4267 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4268 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 4269 } 4270 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4271 #if 1 4272 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4273 for (p = 0; p < 2+size; ++p) { 4274 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); 4275 } 4276 #endif 4277 } 4278 /* Face vertices have 4 + cells supports */ 4279 for (f = fStart; f < fEnd; ++f) { 4280 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4281 const PetscInt *cone, *support; 4282 PetscInt size, s; 4283 4284 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4285 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4286 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4287 for (s = 0; s < size; ++s) { 4288 PetscInt r; 4289 4290 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4291 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4292 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 4293 } 4294 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4295 #if 1 4296 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4297 for (p = 0; p < 4+size; ++p) { 4298 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); 4299 } 4300 #endif 4301 } 4302 /* Cell vertices have 6 supports */ 4303 for (c = cStart; c < cEnd; ++c) { 4304 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4305 PetscInt supportNew[6]; 4306 4307 for (r = 0; r < 6; ++r) { 4308 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4309 } 4310 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4311 } 4312 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4313 break; 4314 case 8: 4315 /* Hybrid Hex 3D */ 4316 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4317 /* 4318 Bottom (viewed from top) Top 4319 1---------2---------2 7---------2---------6 4320 | | | | | | 4321 | B 2 C | | H 2 G | 4322 | | | | | | 4323 3----3----0----1----1 3----3----0----1----1 4324 | | | | | | 4325 | A 0 D | | E 0 F | 4326 | | | | | | 4327 0---------0---------3 4---------0---------5 4328 */ 4329 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4330 for (c = cStart; c < cMax; ++c) { 4331 const PetscInt newp = (c - cStart)*8; 4332 const PetscInt *cone, *ornt; 4333 PetscInt coneNew[6], orntNew[6]; 4334 4335 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4336 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4337 /* A hex */ 4338 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4339 orntNew[0] = ornt[0]; 4340 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4341 orntNew[1] = 0; 4342 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4343 orntNew[2] = ornt[2]; 4344 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4345 orntNew[3] = 0; 4346 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4347 orntNew[4] = 0; 4348 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4349 orntNew[5] = ornt[5]; 4350 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4351 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4352 #if 1 4353 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); 4354 for (p = 0; p < 6; ++p) { 4355 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); 4356 } 4357 #endif 4358 /* B hex */ 4359 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4360 orntNew[0] = ornt[0]; 4361 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4362 orntNew[1] = 0; 4363 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4364 orntNew[2] = -1; 4365 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4366 orntNew[3] = ornt[3]; 4367 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4368 orntNew[4] = 0; 4369 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4370 orntNew[5] = ornt[5]; 4371 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4372 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4373 #if 1 4374 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); 4375 for (p = 0; p < 6; ++p) { 4376 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); 4377 } 4378 #endif 4379 /* C hex */ 4380 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4381 orntNew[0] = ornt[0]; 4382 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4383 orntNew[1] = 0; 4384 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4385 orntNew[2] = -1; 4386 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4387 orntNew[3] = ornt[3]; 4388 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4389 orntNew[4] = ornt[4]; 4390 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4391 orntNew[5] = -4; 4392 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4393 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4394 #if 1 4395 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); 4396 for (p = 0; p < 6; ++p) { 4397 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); 4398 } 4399 #endif 4400 /* D hex */ 4401 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4402 orntNew[0] = ornt[0]; 4403 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4404 orntNew[1] = 0; 4405 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4406 orntNew[2] = ornt[2]; 4407 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4408 orntNew[3] = 0; 4409 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4410 orntNew[4] = ornt[4]; 4411 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4412 orntNew[5] = -4; 4413 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4414 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4415 #if 1 4416 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); 4417 for (p = 0; p < 6; ++p) { 4418 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); 4419 } 4420 #endif 4421 /* E hex */ 4422 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4423 orntNew[0] = -4; 4424 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4425 orntNew[1] = ornt[1]; 4426 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4427 orntNew[2] = ornt[2]; 4428 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4429 orntNew[3] = 0; 4430 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4431 orntNew[4] = -1; 4432 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4433 orntNew[5] = ornt[5]; 4434 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4435 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4436 #if 1 4437 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); 4438 for (p = 0; p < 6; ++p) { 4439 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); 4440 } 4441 #endif 4442 /* F hex */ 4443 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4444 orntNew[0] = -4; 4445 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4446 orntNew[1] = ornt[1]; 4447 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4448 orntNew[2] = ornt[2]; 4449 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4450 orntNew[3] = -1; 4451 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4452 orntNew[4] = ornt[4]; 4453 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4454 orntNew[5] = 1; 4455 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4456 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4457 #if 1 4458 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); 4459 for (p = 0; p < 6; ++p) { 4460 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); 4461 } 4462 #endif 4463 /* G hex */ 4464 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4465 orntNew[0] = -4; 4466 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4467 orntNew[1] = ornt[1]; 4468 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4469 orntNew[2] = 0; 4470 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4471 orntNew[3] = ornt[3]; 4472 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4473 orntNew[4] = ornt[4]; 4474 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4475 orntNew[5] = -3; 4476 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4477 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4478 #if 1 4479 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); 4480 for (p = 0; p < 6; ++p) { 4481 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); 4482 } 4483 #endif 4484 /* H hex */ 4485 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4486 orntNew[0] = -4; 4487 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4488 orntNew[1] = ornt[1]; 4489 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4490 orntNew[2] = -1; 4491 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4492 orntNew[3] = ornt[3]; 4493 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4494 orntNew[4] = 3; 4495 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4496 orntNew[5] = ornt[5]; 4497 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4498 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4499 #if 1 4500 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); 4501 for (p = 0; p < 6; ++p) { 4502 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); 4503 } 4504 #endif 4505 } 4506 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4507 /* 4508 3---------2---------2 4509 | | | 4510 | D 2 C | 4511 | | | 4512 3----3----0----1----1 4513 | | | 4514 | A 0 B | 4515 | | | 4516 0---------0---------1 4517 */ 4518 for (c = cMax; c < cEnd; ++c) { 4519 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4520 const PetscInt *cone, *ornt, *fornt; 4521 PetscInt coneNew[6], orntNew[6]; 4522 4523 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4524 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4525 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4526 for (r = 0; r < 4; ++r) { 4527 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4528 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4529 PetscInt edgeB = (edgeA+3)%4; 4530 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]); 4531 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4532 orntNew[0] = ornt[0]; 4533 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4534 orntNew[1] = ornt[0]; 4535 coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0); 4536 orntNew[(r+0)%4+2] = ornt[edgeA]; 4537 coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4538 orntNew[(r+1)%4+2] = 0; 4539 coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4540 orntNew[(r+2)%4+2] = -2; 4541 coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1); 4542 orntNew[(r+3)%4+2] = ornt[edgeB]; 4543 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4544 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4545 #if 1 4546 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); 4547 for (p = 0; p < 2; ++p) { 4548 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); 4549 } 4550 for (p = 2; p < 6; ++p) { 4551 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); 4552 } 4553 #endif 4554 } 4555 } 4556 /* Interior split faces have 4 edges and the same cells as the parent */ 4557 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4558 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 4559 for (f = fStart; f < fMax; ++f) { 4560 for (r = 0; r < 4; ++r) { 4561 /* TODO: This can come from GetFaces_Internal() */ 4562 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}; 4563 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4564 const PetscInt *cone, *ornt, *support; 4565 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4566 4567 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4568 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4569 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4570 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4571 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4572 orntNew[(r+0)%4] = ornt[r]; 4573 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4574 orntNew[(r+1)%4] = 0; 4575 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4576 orntNew[(r+2)%4] = -2; 4577 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4578 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4579 #if 1 4580 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4581 for (p = 0; p < 4; ++p) { 4582 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); 4583 } 4584 #endif 4585 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4586 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4587 for (s = 0; s < supportSize; ++s) { 4588 PetscInt subf; 4589 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4590 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4591 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4592 for (c = 0; c < coneSize; ++c) { 4593 if (cone[c] == f) break; 4594 } 4595 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4596 if (support[s] < cMax) { 4597 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4598 } else { 4599 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4600 } 4601 } 4602 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4603 #if 1 4604 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4605 for (p = 0; p < supportSize; ++p) { 4606 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); 4607 } 4608 #endif 4609 } 4610 } 4611 /* Interior faces have 4 edges and 2 cells */ 4612 for (c = cStart; c < cMax; ++c) { 4613 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}; 4614 const PetscInt *cone, *ornt; 4615 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4616 4617 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4618 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4619 /* A-D face */ 4620 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4621 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4622 orntNew[0] = 0; 4623 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4624 orntNew[1] = 0; 4625 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4626 orntNew[2] = -2; 4627 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4628 orntNew[3] = -2; 4629 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4630 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4631 #if 1 4632 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4633 for (p = 0; p < 4; ++p) { 4634 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); 4635 } 4636 #endif 4637 /* C-D face */ 4638 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4639 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4640 orntNew[0] = 0; 4641 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4642 orntNew[1] = 0; 4643 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4644 orntNew[2] = -2; 4645 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4646 orntNew[3] = -2; 4647 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4648 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4649 #if 1 4650 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4651 for (p = 0; p < 4; ++p) { 4652 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); 4653 } 4654 #endif 4655 /* B-C face */ 4656 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4657 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4658 orntNew[0] = -2; 4659 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4660 orntNew[1] = 0; 4661 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4662 orntNew[2] = 0; 4663 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4664 orntNew[3] = -2; 4665 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4666 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4667 #if 1 4668 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4669 for (p = 0; p < 4; ++p) { 4670 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); 4671 } 4672 #endif 4673 /* A-B face */ 4674 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4675 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4676 orntNew[0] = -2; 4677 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4678 orntNew[1] = 0; 4679 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4680 orntNew[2] = 0; 4681 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4682 orntNew[3] = -2; 4683 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4684 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4685 #if 1 4686 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4687 for (p = 0; p < 4; ++p) { 4688 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); 4689 } 4690 #endif 4691 /* E-F face */ 4692 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4693 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4694 orntNew[0] = -2; 4695 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4696 orntNew[1] = -2; 4697 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4698 orntNew[2] = 0; 4699 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4700 orntNew[3] = 0; 4701 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4702 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4703 #if 1 4704 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4705 for (p = 0; p < 4; ++p) { 4706 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); 4707 } 4708 #endif 4709 /* F-G face */ 4710 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4711 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4712 orntNew[0] = -2; 4713 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4714 orntNew[1] = -2; 4715 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4716 orntNew[2] = 0; 4717 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4718 orntNew[3] = 0; 4719 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4720 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4721 #if 1 4722 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4723 for (p = 0; p < 4; ++p) { 4724 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); 4725 } 4726 #endif 4727 /* G-H face */ 4728 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4729 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4730 orntNew[0] = -2; 4731 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4732 orntNew[1] = 0; 4733 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4734 orntNew[2] = 0; 4735 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4736 orntNew[3] = -2; 4737 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4738 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4739 #if 1 4740 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4741 for (p = 0; p < 4; ++p) { 4742 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); 4743 } 4744 #endif 4745 /* E-H face */ 4746 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4747 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4748 orntNew[0] = -2; 4749 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4750 orntNew[1] = -2; 4751 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4752 orntNew[2] = 0; 4753 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4754 orntNew[3] = 0; 4755 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4756 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4757 #if 1 4758 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4759 for (p = 0; p < 4; ++p) { 4760 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); 4761 } 4762 #endif 4763 /* A-E face */ 4764 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4765 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4766 orntNew[0] = 0; 4767 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4768 orntNew[1] = 0; 4769 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4770 orntNew[2] = -2; 4771 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4772 orntNew[3] = -2; 4773 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4774 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4775 #if 1 4776 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4777 for (p = 0; p < 4; ++p) { 4778 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); 4779 } 4780 #endif 4781 /* D-F face */ 4782 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4783 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4784 orntNew[0] = -2; 4785 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4786 orntNew[1] = 0; 4787 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4788 orntNew[2] = 0; 4789 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4790 orntNew[3] = -2; 4791 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4792 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4793 #if 1 4794 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4795 for (p = 0; p < 4; ++p) { 4796 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); 4797 } 4798 #endif 4799 /* C-G face */ 4800 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4801 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4802 orntNew[0] = -2; 4803 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4804 orntNew[1] = -2; 4805 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4806 orntNew[2] = 0; 4807 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4808 orntNew[3] = 0; 4809 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4810 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4811 #if 1 4812 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4813 for (p = 0; p < 4; ++p) { 4814 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); 4815 } 4816 #endif 4817 /* B-H face */ 4818 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 4819 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4820 orntNew[0] = 0; 4821 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4822 orntNew[1] = -2; 4823 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4824 orntNew[2] = -2; 4825 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4826 orntNew[3] = 0; 4827 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4828 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4829 #if 1 4830 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4831 for (p = 0; p < 4; ++p) { 4832 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); 4833 } 4834 #endif 4835 for (r = 0; r < 12; ++r) { 4836 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 4837 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4838 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4839 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4840 #if 1 4841 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4842 for (p = 0; p < 2; ++p) { 4843 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); 4844 } 4845 #endif 4846 } 4847 } 4848 /* Hybrid split faces have 4 edges and same cells */ 4849 for (f = fMax; f < fEnd; ++f) { 4850 const PetscInt *cone, *ornt, *support; 4851 PetscInt coneNew[4], orntNew[4]; 4852 PetscInt supportNew[2], size, s, c; 4853 4854 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4855 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4856 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4857 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4858 for (r = 0; r < 2; ++r) { 4859 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 4860 4861 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4862 orntNew[0] = ornt[0]; 4863 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4864 orntNew[1] = ornt[1]; 4865 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 4866 orntNew[2+r] = 0; 4867 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4868 orntNew[3-r] = 0; 4869 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4870 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4871 #if 1 4872 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4873 for (p = 0; p < 2; ++p) { 4874 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); 4875 } 4876 for (p = 2; p < 4; ++p) { 4877 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); 4878 } 4879 #endif 4880 for (s = 0; s < size; ++s) { 4881 const PetscInt *coneCell, *orntCell, *fornt; 4882 4883 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4884 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4885 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 4886 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 4887 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4888 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%4; 4889 } 4890 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4891 #if 1 4892 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4893 for (p = 0; p < size; ++p) { 4894 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); 4895 } 4896 #endif 4897 } 4898 } 4899 /* Hybrid cell faces have 4 edges and 2 cells */ 4900 for (c = cMax; c < cEnd; ++c) { 4901 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 4902 const PetscInt *cone, *ornt; 4903 PetscInt coneNew[4], orntNew[4]; 4904 PetscInt supportNew[2]; 4905 4906 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4907 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4908 for (r = 0; r < 4; ++r) { 4909 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 4910 orntNew[0] = 0; 4911 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 4912 orntNew[1] = 0; 4913 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 4914 orntNew[2] = 0; 4915 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4916 orntNew[3] = 0; 4917 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4918 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4919 #if 1 4920 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); 4921 for (p = 0; p < 2; ++p) { 4922 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); 4923 } 4924 for (p = 2; p < 4; ++p) { 4925 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); 4926 } 4927 #endif 4928 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 4929 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 4930 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4931 #if 1 4932 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); 4933 for (p = 0; p < 2; ++p) { 4934 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); 4935 } 4936 #endif 4937 } 4938 } 4939 /* Interior split edges have 2 vertices and the same faces as the parent */ 4940 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4941 for (e = eStart; e < eMax; ++e) { 4942 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4943 4944 for (r = 0; r < 2; ++r) { 4945 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4946 const PetscInt *cone, *ornt, *support; 4947 PetscInt coneNew[2], coneSize, c, supportSize, s; 4948 4949 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4950 coneNew[0] = vStartNew + (cone[0] - vStart); 4951 coneNew[1] = vStartNew + (cone[1] - vStart); 4952 coneNew[(r+1)%2] = newv; 4953 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4954 #if 1 4955 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4956 for (p = 0; p < 2; ++p) { 4957 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); 4958 } 4959 #endif 4960 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4961 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4962 for (s = 0; s < supportSize; ++s) { 4963 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4964 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4965 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4966 for (c = 0; c < coneSize; ++c) { 4967 if (cone[c] == e) break; 4968 } 4969 if (support[s] < fMax) { 4970 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 4971 } else { 4972 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4973 } 4974 } 4975 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4976 #if 1 4977 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4978 for (p = 0; p < supportSize; ++p) { 4979 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); 4980 } 4981 #endif 4982 } 4983 } 4984 /* Interior face edges have 2 vertices and 2+cells faces */ 4985 for (f = fStart; f < fMax; ++f) { 4986 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}; 4987 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 4988 const PetscInt *cone, *coneCell, *orntCell, *support; 4989 PetscInt coneNew[2], coneSize, c, supportSize, s; 4990 4991 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4992 for (r = 0; r < 4; ++r) { 4993 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4994 4995 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4996 coneNew[1] = newv; 4997 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4998 #if 1 4999 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5000 for (p = 0; p < 2; ++p) { 5001 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); 5002 } 5003 #endif 5004 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5005 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5006 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5007 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5008 for (s = 0; s < supportSize; ++s) { 5009 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5010 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5011 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5012 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5013 if (support[s] < cMax) { 5014 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5015 } else { 5016 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r); 5017 } 5018 } 5019 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5020 #if 1 5021 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5022 for (p = 0; p < 2+supportSize; ++p) { 5023 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); 5024 } 5025 #endif 5026 } 5027 } 5028 /* Interior cell edges have 2 vertices and 4 faces */ 5029 for (c = cStart; c < cMax; ++c) { 5030 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}; 5031 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5032 const PetscInt *cone; 5033 PetscInt coneNew[2], supportNew[4]; 5034 5035 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5036 for (r = 0; r < 6; ++r) { 5037 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5038 5039 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5040 coneNew[1] = newv; 5041 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5042 #if 1 5043 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5044 for (p = 0; p < 2; ++p) { 5045 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); 5046 } 5047 #endif 5048 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5049 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5050 #if 1 5051 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5052 for (p = 0; p < 4; ++p) { 5053 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); 5054 } 5055 #endif 5056 } 5057 } 5058 /* Hybrid edges have two vertices and the same faces */ 5059 for (e = eMax; e < eEnd; ++e) { 5060 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5061 const PetscInt *cone, *support, *fcone; 5062 PetscInt coneNew[2], size, fsize, s; 5063 5064 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5065 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5066 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5067 coneNew[0] = vStartNew + (cone[0] - vStart); 5068 coneNew[1] = vStartNew + (cone[1] - vStart); 5069 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5070 #if 1 5071 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5072 for (p = 0; p < 2; ++p) { 5073 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); 5074 } 5075 #endif 5076 for (s = 0; s < size; ++s) { 5077 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5078 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5079 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5080 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5081 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 5082 } 5083 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5084 #if 1 5085 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5086 for (p = 0; p < size; ++p) { 5087 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); 5088 } 5089 #endif 5090 } 5091 /* Hybrid face edges have 2 vertices and 2+cells faces */ 5092 for (f = fMax; f < fEnd; ++f) { 5093 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5094 const PetscInt *cone, *support, *ccone, *cornt; 5095 PetscInt coneNew[2], size, csize, s; 5096 5097 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5098 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5099 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5100 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5101 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 5102 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5103 #if 1 5104 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5105 for (p = 0; p < 2; ++p) { 5106 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); 5107 } 5108 #endif 5109 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 5110 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5111 for (s = 0; s < size; ++s) { 5112 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5113 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5114 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5115 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5116 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]); 5117 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadSubfaceInverse_Static(cornt[0], c-2); 5118 } 5119 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5120 #if 1 5121 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5122 for (p = 0; p < 2+size; ++p) { 5123 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); 5124 } 5125 #endif 5126 } 5127 /* Hybrid cell edges have 2 vertices and 4 faces */ 5128 for (c = cMax; c < cEnd; ++c) { 5129 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5130 const PetscInt *cone, *support; 5131 PetscInt coneNew[2], size; 5132 5133 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5134 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5135 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5136 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5137 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5138 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5139 #if 1 5140 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5141 for (p = 0; p < 2; ++p) { 5142 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); 5143 } 5144 #endif 5145 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5146 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5147 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5148 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5149 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5150 #if 1 5151 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5152 for (p = 0; p < 4; ++p) { 5153 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); 5154 } 5155 #endif 5156 } 5157 /* Interior vertices have identical supports */ 5158 for (v = vStart; v < vEnd; ++v) { 5159 const PetscInt newp = vStartNew + (v - vStart); 5160 const PetscInt *support, *cone; 5161 PetscInt size, s; 5162 5163 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5164 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5165 for (s = 0; s < size; ++s) { 5166 PetscInt r = 0; 5167 5168 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5169 if (cone[1] == v) r = 1; 5170 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5171 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5172 } 5173 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5174 #if 1 5175 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5176 for (p = 0; p < size; ++p) { 5177 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); 5178 } 5179 #endif 5180 } 5181 /* Interior edge vertices have 2 + faces supports */ 5182 for (e = eStart; e < eMax; ++e) { 5183 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5184 const PetscInt *cone, *support; 5185 PetscInt size, s; 5186 5187 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5188 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5189 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5190 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5191 for (s = 0; s < size; ++s) { 5192 PetscInt r; 5193 5194 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5195 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5196 if (support[s] < fMax) { 5197 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5198 } else { 5199 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5200 } 5201 } 5202 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5203 #if 1 5204 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5205 for (p = 0; p < 2+size; ++p) { 5206 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); 5207 } 5208 #endif 5209 } 5210 /* Interior face vertices have 4 + cells supports */ 5211 for (f = fStart; f < fMax; ++f) { 5212 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5213 const PetscInt *cone, *support; 5214 PetscInt size, s; 5215 5216 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5217 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5218 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5219 for (s = 0; s < size; ++s) { 5220 PetscInt r; 5221 5222 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5223 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5224 if (support[s] < cMax) { 5225 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5226 } else { 5227 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5228 } 5229 } 5230 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5231 #if 1 5232 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5233 for (p = 0; p < 4+size; ++p) { 5234 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); 5235 } 5236 #endif 5237 } 5238 /* Cell vertices have 6 supports */ 5239 for (c = cStart; c < cMax; ++c) { 5240 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5241 PetscInt supportNew[6]; 5242 5243 for (r = 0; r < 6; ++r) { 5244 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5245 } 5246 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5247 } 5248 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5249 break; 5250 default: 5251 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5252 } 5253 PetscFunctionReturn(0); 5254 } 5255 5256 #undef __FUNCT__ 5257 #define __FUNCT__ "CellRefinerSetCoordinates" 5258 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5259 { 5260 PetscSection coordSection, coordSectionNew; 5261 Vec coordinates, coordinatesNew; 5262 PetscScalar *coords, *coordsNew; 5263 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5264 PetscInt dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5265 PetscErrorCode ierr; 5266 5267 PetscFunctionBegin; 5268 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 5269 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5270 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5271 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5272 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5273 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5274 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5275 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5276 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5277 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5278 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5279 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5280 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 5281 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5282 if (cMax < 0) cMax = cEnd; 5283 if (fMax < 0) fMax = fEnd; 5284 if (eMax < 0) eMax = eEnd; 5285 /* All vertices have the dim coordinates */ 5286 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5287 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 5288 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 5289 } 5290 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5291 ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 5292 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5293 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5294 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 5295 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5296 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5297 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 5298 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5299 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5300 switch (refiner) { 5301 case 0: break; 5302 case 6: /* Hex 3D */ 5303 case 8: /* Hybrid Hex 3D */ 5304 /* Face vertices have the average of corner coordinates */ 5305 for (f = fStart; f < fMax; ++f) { 5306 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5307 PetscInt *cone = NULL; 5308 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5309 5310 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5311 for (p = 0; p < closureSize*2; p += 2) { 5312 const PetscInt point = cone[p]; 5313 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5314 } 5315 for (v = 0; v < coneSize; ++v) { 5316 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5317 } 5318 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5319 for (d = 0; d < dim; ++d) { 5320 coordsNew[offnew+d] = 0.0; 5321 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5322 coordsNew[offnew+d] /= coneSize; 5323 } 5324 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5325 } 5326 case 2: /* Hex 2D */ 5327 case 4: /* Hybrid Hex 2D */ 5328 /* Cell vertices have the average of corner coordinates */ 5329 for (c = cStart; c < cMax; ++c) { 5330 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 5331 PetscInt *cone = NULL; 5332 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5333 5334 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5335 for (p = 0; p < closureSize*2; p += 2) { 5336 const PetscInt point = cone[p]; 5337 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5338 } 5339 for (v = 0; v < coneSize; ++v) { 5340 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5341 } 5342 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5343 for (d = 0; d < dim; ++d) { 5344 coordsNew[offnew+d] = 0.0; 5345 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5346 coordsNew[offnew+d] /= coneSize; 5347 } 5348 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5349 } 5350 case 1: /* Simplicial 2D */ 5351 case 3: /* Hybrid Simplicial 2D */ 5352 case 5: /* Simplicial 3D */ 5353 case 7: /* Hybrid Simplicial 3D */ 5354 /* Edge vertices have the average of endpoint coordinates */ 5355 for (e = eStart; e < eMax; ++e) { 5356 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5357 const PetscInt *cone; 5358 PetscInt coneSize, offA, offB, offnew, d; 5359 5360 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5361 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5362 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5363 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5364 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5365 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5366 for (d = 0; d < dim; ++d) { 5367 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 5368 } 5369 } 5370 /* Old vertices have the same coordinates */ 5371 for (v = vStart; v < vEnd; ++v) { 5372 const PetscInt newv = vStartNew + (v - vStart); 5373 PetscInt off, offnew, d; 5374 5375 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5376 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5377 for (d = 0; d < dim; ++d) { 5378 coordsNew[offnew+d] = coords[off+d]; 5379 } 5380 } 5381 break; 5382 default: 5383 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5384 } 5385 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5386 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5387 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5388 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5389 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5390 PetscFunctionReturn(0); 5391 } 5392 5393 #undef __FUNCT__ 5394 #define __FUNCT__ "DMPlexCreateProcessSF" 5395 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5396 { 5397 PetscInt numRoots, numLeaves, l; 5398 const PetscInt *localPoints; 5399 const PetscSFNode *remotePoints; 5400 PetscInt *localPointsNew; 5401 PetscSFNode *remotePointsNew; 5402 PetscInt *ranks, *ranksNew; 5403 PetscErrorCode ierr; 5404 5405 PetscFunctionBegin; 5406 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5407 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5408 for (l = 0; l < numLeaves; ++l) { 5409 ranks[l] = remotePoints[l].rank; 5410 } 5411 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5412 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5413 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5414 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5415 for (l = 0; l < numLeaves; ++l) { 5416 ranksNew[l] = ranks[l]; 5417 localPointsNew[l] = l; 5418 remotePointsNew[l].index = 0; 5419 remotePointsNew[l].rank = ranksNew[l]; 5420 } 5421 ierr = PetscFree(ranks);CHKERRQ(ierr); 5422 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 5423 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5424 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5425 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5426 PetscFunctionReturn(0); 5427 } 5428 5429 #undef __FUNCT__ 5430 #define __FUNCT__ "CellRefinerCreateSF" 5431 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5432 { 5433 PetscSF sf, sfNew, sfProcess; 5434 IS processRanks; 5435 MPI_Datatype depthType; 5436 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5437 const PetscInt *localPoints, *neighbors; 5438 const PetscSFNode *remotePoints; 5439 PetscInt *localPointsNew; 5440 PetscSFNode *remotePointsNew; 5441 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5442 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5443 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5444 PetscErrorCode ierr; 5445 5446 PetscFunctionBegin; 5447 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5448 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5449 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5450 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5451 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5452 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5453 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5454 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5455 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5456 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5457 /* Caculate size of new SF */ 5458 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5459 if (numRoots < 0) PetscFunctionReturn(0); 5460 for (l = 0; l < numLeaves; ++l) { 5461 const PetscInt p = localPoints[l]; 5462 5463 switch (refiner) { 5464 case 1: 5465 /* Simplicial 2D */ 5466 if ((p >= vStart) && (p < vEnd)) { 5467 /* Old vertices stay the same */ 5468 ++numLeavesNew; 5469 } else if ((p >= fStart) && (p < fEnd)) { 5470 /* Old faces add new faces and vertex */ 5471 numLeavesNew += 2 + 1; 5472 } else if ((p >= cStart) && (p < cEnd)) { 5473 /* Old cells add new cells and interior faces */ 5474 numLeavesNew += 4 + 3; 5475 } 5476 break; 5477 case 3: 5478 /* Hybrid Simplicial 2D */ 5479 if ((p >= vStart) && (p < vEnd)) { 5480 /* Interior vertices stay the same */ 5481 ++numLeavesNew; 5482 } else if ((p >= fStart) && (p < fMax)) { 5483 /* Interior faces add new faces and vertex */ 5484 numLeavesNew += 2 + 1; 5485 } else if ((p >= fMax) && (p < fEnd)) { 5486 /* Hybrid faces stay the same */ 5487 ++numLeavesNew; 5488 } else if ((p >= cStart) && (p < cMax)) { 5489 /* Interior cells add new cells and interior faces */ 5490 numLeavesNew += 4 + 3; 5491 } else if ((p >= cMax) && (p < cEnd)) { 5492 /* Hybrid cells add new cells and hybrid face */ 5493 numLeavesNew += 2 + 1; 5494 } 5495 break; 5496 case 2: 5497 /* Hex 2D */ 5498 if ((p >= vStart) && (p < vEnd)) { 5499 /* Old vertices stay the same */ 5500 ++numLeavesNew; 5501 } else if ((p >= fStart) && (p < fEnd)) { 5502 /* Old faces add new faces and vertex */ 5503 numLeavesNew += 2 + 1; 5504 } else if ((p >= cStart) && (p < cEnd)) { 5505 /* Old cells add new cells, interior faces, and vertex */ 5506 numLeavesNew += 4 + 4 + 1; 5507 } 5508 break; 5509 case 4: 5510 /* Hybrid Hex 2D */ 5511 if ((p >= vStart) && (p < vEnd)) { 5512 /* Interior vertices stay the same */ 5513 ++numLeavesNew; 5514 } else if ((p >= fStart) && (p < fMax)) { 5515 /* Interior faces add new faces and vertex */ 5516 numLeavesNew += 2 + 1; 5517 } else if ((p >= fMax) && (p < fEnd)) { 5518 /* Hybrid faces stay the same */ 5519 ++numLeavesNew; 5520 } else if ((p >= cStart) && (p < cMax)) { 5521 /* Interior cells add new cells, interior faces, and vertex */ 5522 numLeavesNew += 4 + 4 + 1; 5523 } else if ((p >= cMax) && (p < cEnd)) { 5524 /* Hybrid cells add new cells and hybrid face */ 5525 numLeavesNew += 2 + 1; 5526 } 5527 break; 5528 case 5: 5529 /* Simplicial 3D */ 5530 if ((p >= vStart) && (p < vEnd)) { 5531 /* Old vertices stay the same */ 5532 ++numLeavesNew; 5533 } else if ((p >= eStart) && (p < eEnd)) { 5534 /* Old edges add new edges and vertex */ 5535 numLeavesNew += 2 + 1; 5536 } else if ((p >= fStart) && (p < fEnd)) { 5537 /* Old faces add new faces and face edges */ 5538 numLeavesNew += 4 + 3; 5539 } else if ((p >= cStart) && (p < cEnd)) { 5540 /* Old cells add new cells and interior faces and edges */ 5541 numLeavesNew += 8 + 8 + 1; 5542 } 5543 break; 5544 case 7: 5545 /* Hybrid Simplicial 3D */ 5546 if ((p >= vStart) && (p < vEnd)) { 5547 /* Interior vertices stay the same */ 5548 ++numLeavesNew; 5549 } else if ((p >= eStart) && (p < eMax)) { 5550 /* Interior edges add new edges and vertex */ 5551 numLeavesNew += 2 + 1; 5552 } else if ((p >= eMax) && (p < eEnd)) { 5553 /* Hybrid edges stay the same */ 5554 ++numLeavesNew; 5555 } else if ((p >= fStart) && (p < fMax)) { 5556 /* Interior faces add new faces and edges */ 5557 numLeavesNew += 4 + 3; 5558 } else if ((p >= fMax) && (p < fEnd)) { 5559 /* Hybrid faces add new faces and edges */ 5560 numLeavesNew += 2 + 1; 5561 } else if ((p >= cStart) && (p < cMax)) { 5562 /* Interior cells add new cells, faces, and edges */ 5563 numLeavesNew += 8 + 8 + 1; 5564 } else if ((p >= cMax) && (p < cEnd)) { 5565 /* Hybrid cells add new cells and faces */ 5566 numLeavesNew += 4 + 3; 5567 } 5568 break; 5569 case 6: 5570 /* Hex 3D */ 5571 if ((p >= vStart) && (p < vEnd)) { 5572 /* Old vertices stay the same */ 5573 ++numLeavesNew; 5574 } else if ((p >= eStart) && (p < eEnd)) { 5575 /* Old edges add new edges, and vertex */ 5576 numLeavesNew += 2 + 1; 5577 } else if ((p >= fStart) && (p < fEnd)) { 5578 /* Old faces add new faces, edges, and vertex */ 5579 numLeavesNew += 4 + 4 + 1; 5580 } else if ((p >= cStart) && (p < cEnd)) { 5581 /* Old cells add new cells, faces, edges, and vertex */ 5582 numLeavesNew += 8 + 12 + 6 + 1; 5583 } 5584 break; 5585 case 8: 5586 /* Hybrid Hex 3D */ 5587 if ((p >= vStart) && (p < vEnd)) { 5588 /* Old vertices stay the same */ 5589 ++numLeavesNew; 5590 } else if ((p >= eStart) && (p < eMax)) { 5591 /* Interior edges add new edges, and vertex */ 5592 numLeavesNew += 2 + 1; 5593 } else if ((p >= eMax) && (p < eEnd)) { 5594 /* Hybrid edges stay the same */ 5595 ++numLeavesNew; 5596 } else if ((p >= fStart) && (p < fMax)) { 5597 /* Interior faces add new faces, edges, and vertex */ 5598 numLeavesNew += 4 + 4 + 1; 5599 } else if ((p >= fMax) && (p < fEnd)) { 5600 /* Hybrid faces add new faces and edges */ 5601 numLeavesNew += 2 + 1; 5602 } else if ((p >= cStart) && (p < cMax)) { 5603 /* Interior cells add new cells, faces, edges, and vertex */ 5604 numLeavesNew += 8 + 12 + 6 + 1; 5605 } else if ((p >= cStart) && (p < cEnd)) { 5606 /* Hybrid cells add new cells, faces, and edges */ 5607 numLeavesNew += 4 + 4 + 1; 5608 } 5609 break; 5610 default: 5611 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5612 } 5613 } 5614 /* Communicate depthSizes for each remote rank */ 5615 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5616 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5617 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5618 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5619 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5620 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5621 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5622 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5623 for (n = 0; n < numNeighbors; ++n) { 5624 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5625 } 5626 depthSizeOld[depth] = cMax; 5627 depthSizeOld[0] = vMax; 5628 depthSizeOld[depth-1] = fMax; 5629 depthSizeOld[1] = eMax; 5630 5631 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5632 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5633 5634 depthSizeOld[depth] = cEnd - cStart; 5635 depthSizeOld[0] = vEnd - vStart; 5636 depthSizeOld[depth-1] = fEnd - fStart; 5637 depthSizeOld[1] = eEnd - eStart; 5638 5639 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5640 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5641 for (n = 0; n < numNeighbors; ++n) { 5642 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5643 } 5644 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5645 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5646 /* Calculate new point SF */ 5647 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5648 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5649 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5650 for (l = 0, m = 0; l < numLeaves; ++l) { 5651 PetscInt p = localPoints[l]; 5652 PetscInt rp = remotePoints[l].index, n; 5653 PetscMPIInt rrank = remotePoints[l].rank; 5654 5655 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5656 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5657 switch (refiner) { 5658 case 1: 5659 /* Simplicial 2D */ 5660 if ((p >= vStart) && (p < vEnd)) { 5661 /* Old vertices stay the same */ 5662 localPointsNew[m] = vStartNew + (p - vStart); 5663 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5664 remotePointsNew[m].rank = rrank; 5665 ++m; 5666 } else if ((p >= fStart) && (p < fEnd)) { 5667 /* Old faces add new faces and vertex */ 5668 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5669 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5670 remotePointsNew[m].rank = rrank; 5671 ++m; 5672 for (r = 0; r < 2; ++r, ++m) { 5673 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5674 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5675 remotePointsNew[m].rank = rrank; 5676 } 5677 } else if ((p >= cStart) && (p < cEnd)) { 5678 /* Old cells add new cells and interior faces */ 5679 for (r = 0; r < 4; ++r, ++m) { 5680 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5681 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5682 remotePointsNew[m].rank = rrank; 5683 } 5684 for (r = 0; r < 3; ++r, ++m) { 5685 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5686 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 5687 remotePointsNew[m].rank = rrank; 5688 } 5689 } 5690 break; 5691 case 2: 5692 /* Hex 2D */ 5693 if ((p >= vStart) && (p < vEnd)) { 5694 /* Old vertices stay the same */ 5695 localPointsNew[m] = vStartNew + (p - vStart); 5696 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5697 remotePointsNew[m].rank = rrank; 5698 ++m; 5699 } else if ((p >= fStart) && (p < fEnd)) { 5700 /* Old faces add new faces and vertex */ 5701 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5702 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5703 remotePointsNew[m].rank = rrank; 5704 ++m; 5705 for (r = 0; r < 2; ++r, ++m) { 5706 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5707 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5708 remotePointsNew[m].rank = rrank; 5709 } 5710 } else if ((p >= cStart) && (p < cEnd)) { 5711 /* Old cells add new cells, interior faces, and vertex */ 5712 for (r = 0; r < 4; ++r, ++m) { 5713 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5714 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5715 remotePointsNew[m].rank = rrank; 5716 } 5717 for (r = 0; r < 4; ++r, ++m) { 5718 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 5719 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 5720 remotePointsNew[m].rank = rrank; 5721 } 5722 for (r = 0; r < 1; ++r, ++m) { 5723 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart) + r; 5724 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 5725 remotePointsNew[m].rank = rrank; 5726 } 5727 } 5728 break; 5729 case 3: 5730 /* Hybrid simplicial 2D */ 5731 if ((p >= vStart) && (p < vEnd)) { 5732 /* Old vertices stay the same */ 5733 localPointsNew[m] = vStartNew + (p - vStart); 5734 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5735 remotePointsNew[m].rank = rrank; 5736 ++m; 5737 } else if ((p >= fStart) && (p < fMax)) { 5738 /* Old interior faces add new faces and vertex */ 5739 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5740 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5741 remotePointsNew[m].rank = rrank; 5742 ++m; 5743 for (r = 0; r < 2; ++r, ++m) { 5744 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5745 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5746 remotePointsNew[m].rank = rrank; 5747 } 5748 } else if ((p >= fMax) && (p < fEnd)) { 5749 /* Old hybrid faces stay the same */ 5750 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5751 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5752 remotePointsNew[m].rank = rrank; 5753 ++m; 5754 } else if ((p >= cStart) && (p < cMax)) { 5755 /* Old interior cells add new cells and interior faces */ 5756 for (r = 0; r < 4; ++r, ++m) { 5757 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5758 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5759 remotePointsNew[m].rank = rrank; 5760 } 5761 for (r = 0; r < 3; ++r, ++m) { 5762 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5763 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5764 remotePointsNew[m].rank = rrank; 5765 } 5766 } else if ((p >= cStart) && (p < cMax)) { 5767 /* Old hybrid cells add new cells and hybrid face */ 5768 for (r = 0; r < 2; ++r, ++m) { 5769 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5770 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5771 remotePointsNew[m].rank = rrank; 5772 } 5773 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5774 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]); 5775 remotePointsNew[m].rank = rrank; 5776 ++m; 5777 } 5778 break; 5779 case 4: 5780 /* Hybrid Hex 2D */ 5781 if ((p >= vStart) && (p < vEnd)) { 5782 /* Old vertices stay the same */ 5783 localPointsNew[m] = vStartNew + (p - vStart); 5784 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5785 remotePointsNew[m].rank = rrank; 5786 ++m; 5787 } else if ((p >= fStart) && (p < fMax)) { 5788 /* Old interior faces add new faces and vertex */ 5789 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5790 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5791 remotePointsNew[m].rank = rrank; 5792 ++m; 5793 for (r = 0; r < 2; ++r, ++m) { 5794 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5795 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5796 remotePointsNew[m].rank = rrank; 5797 } 5798 } else if ((p >= fMax) && (p < fEnd)) { 5799 /* Old hybrid faces stay the same */ 5800 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5801 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5802 remotePointsNew[m].rank = rrank; 5803 ++m; 5804 } else if ((p >= cStart) && (p < cMax)) { 5805 /* Old interior cells add new cells, interior faces, and vertex */ 5806 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 5807 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 5808 remotePointsNew[m].rank = rrank; 5809 ++m; 5810 for (r = 0; r < 4; ++r, ++m) { 5811 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5812 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5813 remotePointsNew[m].rank = rrank; 5814 } 5815 for (r = 0; r < 4; ++r, ++m) { 5816 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5817 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5818 remotePointsNew[m].rank = rrank; 5819 } 5820 } else if ((p >= cStart) && (p < cMax)) { 5821 /* Old hybrid cells add new cells and hybrid face */ 5822 for (r = 0; r < 2; ++r, ++m) { 5823 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5824 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5825 remotePointsNew[m].rank = rrank; 5826 } 5827 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5828 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]); 5829 remotePointsNew[m].rank = rrank; 5830 ++m; 5831 } 5832 break; 5833 case 5: 5834 /* Simplicial 3D */ 5835 if ((p >= vStart) && (p < vEnd)) { 5836 /* Old vertices stay the same */ 5837 localPointsNew[m] = vStartNew + (p - vStart); 5838 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5839 remotePointsNew[m].rank = rrank; 5840 ++m; 5841 } else if ((p >= eStart) && (p < eEnd)) { 5842 /* Old edges add new edges and vertex */ 5843 for (r = 0; r < 2; ++r, ++m) { 5844 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5845 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5846 remotePointsNew[m].rank = rrank; 5847 } 5848 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5849 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5850 remotePointsNew[m].rank = rrank; 5851 ++m; 5852 } else if ((p >= fStart) && (p < fEnd)) { 5853 /* Old faces add new faces and face edges */ 5854 for (r = 0; r < 4; ++r, ++m) { 5855 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5856 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5857 remotePointsNew[m].rank = rrank; 5858 } 5859 for (r = 0; r < 3; ++r, ++m) { 5860 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 5861 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 5862 remotePointsNew[m].rank = rrank; 5863 } 5864 } else if ((p >= cStart) && (p < cEnd)) { 5865 /* Old cells add new cells and interior faces and edges */ 5866 for (r = 0; r < 8; ++r, ++m) { 5867 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5868 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5869 remotePointsNew[m].rank = rrank; 5870 } 5871 for (r = 0; r < 8; ++r, ++m) { 5872 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 5873 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 5874 remotePointsNew[m].rank = rrank; 5875 } 5876 for (r = 0; r < 1; ++r, ++m) { 5877 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 5878 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 5879 remotePointsNew[m].rank = rrank; 5880 } 5881 } 5882 break; 5883 case 7: 5884 /* Hybrid Simplicial 3D */ 5885 if ((p >= vStart) && (p < vEnd)) { 5886 /* Interior vertices stay the same */ 5887 localPointsNew[m] = vStartNew + (p - vStart); 5888 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5889 remotePointsNew[m].rank = rrank; 5890 ++m; 5891 } else if ((p >= eStart) && (p < eMax)) { 5892 /* Interior edges add new edges and vertex */ 5893 for (r = 0; r < 2; ++r, ++m) { 5894 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5895 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5896 remotePointsNew[m].rank = rrank; 5897 } 5898 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5899 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5900 remotePointsNew[m].rank = rrank; 5901 ++m; 5902 } else if ((p >= eMax) && (p < eEnd)) { 5903 /* Hybrid edges stay the same */ 5904 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5905 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)+1]); 5906 remotePointsNew[m].rank = rrank; 5907 ++m; 5908 } else if ((p >= fStart) && (p < fMax)) { 5909 /* Interior faces add new faces and edges */ 5910 for (r = 0; r < 4; ++r, ++m) { 5911 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5912 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5913 remotePointsNew[m].rank = rrank; 5914 } 5915 for (r = 0; r < 3; ++r, ++m) { 5916 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5917 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5918 remotePointsNew[m].rank = rrank; 5919 } 5920 } else if ((p >= fMax) && (p < fEnd)) { 5921 /* Hybrid faces add new faces and edges */ 5922 for (r = 0; r < 2; ++r, ++m) { 5923 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5924 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; 5925 remotePointsNew[m].rank = rrank; 5926 } 5927 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 5928 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]) + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5929 remotePointsNew[m].rank = rrank; 5930 ++m; 5931 } else if ((p >= cStart) && (p < cMax)) { 5932 /* Interior cells add new cells, faces, and edges */ 5933 for (r = 0; r < 8; ++r, ++m) { 5934 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5935 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5936 remotePointsNew[m].rank = rrank; 5937 } 5938 for (r = 0; r < 8; ++r, ++m) { 5939 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5940 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 5941 remotePointsNew[m].rank = rrank; 5942 } 5943 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 5944 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; 5945 remotePointsNew[m].rank = rrank; 5946 ++m; 5947 } else if ((p >= cMax) && (p < cEnd)) { 5948 /* Hybrid cells add new cells and faces */ 5949 for (r = 0; r < 4; ++r, ++m) { 5950 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5951 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5952 remotePointsNew[m].rank = rrank; 5953 } 5954 for (r = 0; r < 3; ++r, ++m) { 5955 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5956 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; 5957 remotePointsNew[m].rank = rrank; 5958 } 5959 } 5960 break; 5961 case 6: 5962 /* Hex 3D */ 5963 if ((p >= vStart) && (p < vEnd)) { 5964 /* Old vertices stay the same */ 5965 localPointsNew[m] = vStartNew + (p - vStart); 5966 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5967 remotePointsNew[m].rank = rrank; 5968 ++m; 5969 } else if ((p >= eStart) && (p < eEnd)) { 5970 /* Old edges add new edges and vertex */ 5971 for (r = 0; r < 2; ++r, ++m) { 5972 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5973 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5974 remotePointsNew[m].rank = rrank; 5975 } 5976 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5977 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5978 remotePointsNew[m].rank = rrank; 5979 ++m; 5980 } else if ((p >= fStart) && (p < fEnd)) { 5981 /* Old faces add new faces, edges, and vertex */ 5982 for (r = 0; r < 4; ++r, ++m) { 5983 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5984 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5985 remotePointsNew[m].rank = rrank; 5986 } 5987 for (r = 0; r < 4; ++r, ++m) { 5988 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 5989 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 5990 remotePointsNew[m].rank = rrank; 5991 } 5992 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 5993 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 5994 remotePointsNew[m].rank = rrank; 5995 ++m; 5996 } else if ((p >= cStart) && (p < cEnd)) { 5997 /* Old cells add new cells, faces, edges, and vertex */ 5998 for (r = 0; r < 8; ++r, ++m) { 5999 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6000 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6001 remotePointsNew[m].rank = rrank; 6002 } 6003 for (r = 0; r < 12; ++r, ++m) { 6004 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6005 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 6006 remotePointsNew[m].rank = rrank; 6007 } 6008 for (r = 0; r < 6; ++r, ++m) { 6009 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6010 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 6011 remotePointsNew[m].rank = rrank; 6012 } 6013 for (r = 0; r < 1; ++r, ++m) { 6014 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 6015 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 6016 remotePointsNew[m].rank = rrank; 6017 } 6018 } 6019 break; 6020 case 8: 6021 /* Hybrid Hex 3D */ 6022 if ((p >= vStart) && (p < vEnd)) { 6023 /* Interior vertices stay the same */ 6024 localPointsNew[m] = vStartNew + (p - vStart); 6025 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6026 remotePointsNew[m].rank = rrank; 6027 ++m; 6028 } else if ((p >= eStart) && (p < eMax)) { 6029 /* Interior edges add new edges and vertex */ 6030 for (r = 0; r < 2; ++r, ++m) { 6031 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6032 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6033 remotePointsNew[m].rank = rrank; 6034 } 6035 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6036 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6037 remotePointsNew[m].rank = rrank; 6038 ++m; 6039 } else if ((p >= eMax) && (p < eEnd)) { 6040 /* Hybrid edges stay the same */ 6041 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6042 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]); 6043 remotePointsNew[m].rank = rrank; 6044 ++m; 6045 } else if ((p >= fStart) && (p < fMax)) { 6046 /* Interior faces add new faces, edges, and vertex */ 6047 for (r = 0; r < 4; ++r, ++m) { 6048 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6049 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6050 remotePointsNew[m].rank = rrank; 6051 } 6052 for (r = 0; r < 4; ++r, ++m) { 6053 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6054 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 6055 remotePointsNew[m].rank = rrank; 6056 } 6057 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6058 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 6059 remotePointsNew[m].rank = rrank; 6060 ++m; 6061 } else if ((p >= fMax) && (p < fEnd)) { 6062 /* Hybrid faces add new faces and edges */ 6063 for (r = 0; r < 2; ++r, ++m) { 6064 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6065 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; 6066 remotePointsNew[m].rank = rrank; 6067 } 6068 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax); 6069 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]); 6070 remotePointsNew[m].rank = rrank; 6071 ++m; 6072 } else if ((p >= cStart) && (p < cMax)) { 6073 /* Interior cells add new cells, faces, edges, and vertex */ 6074 for (r = 0; r < 8; ++r, ++m) { 6075 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6076 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6077 remotePointsNew[m].rank = rrank; 6078 } 6079 for (r = 0; r < 12; ++r, ++m) { 6080 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6081 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6082 remotePointsNew[m].rank = rrank; 6083 } 6084 for (r = 0; r < 6; ++r, ++m) { 6085 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6086 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; 6087 remotePointsNew[m].rank = rrank; 6088 } 6089 for (r = 0; r < 1; ++r, ++m) { 6090 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6091 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6092 remotePointsNew[m].rank = rrank; 6093 } 6094 } else if ((p >= cMax) && (p < cEnd)) { 6095 /* Hybrid cells add new cells, faces, and edges */ 6096 for (r = 0; r < 4; ++r, ++m) { 6097 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6098 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6099 remotePointsNew[m].rank = rrank; 6100 } 6101 for (r = 0; r < 4; ++r, ++m) { 6102 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6103 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; 6104 remotePointsNew[m].rank = rrank; 6105 } 6106 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6107 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]); 6108 remotePointsNew[m].rank = rrank; 6109 ++m; 6110 } 6111 break; 6112 default: 6113 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6114 } 6115 } 6116 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6117 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6118 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6119 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6120 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6121 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6122 PetscFunctionReturn(0); 6123 } 6124 6125 #undef __FUNCT__ 6126 #define __FUNCT__ "CellRefinerCreateLabels" 6127 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6128 { 6129 PetscInt numLabels, l; 6130 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6131 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6132 PetscErrorCode ierr; 6133 6134 PetscFunctionBegin; 6135 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6136 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6137 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6138 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6139 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6140 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6141 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6142 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6143 switch (refiner) { 6144 case 0: break; 6145 case 7: 6146 case 8: 6147 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6148 case 3: 6149 case 4: 6150 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6151 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6152 } 6153 for (l = 0; l < numLabels; ++l) { 6154 DMLabel label, labelNew; 6155 const char *lname; 6156 PetscBool isDepth; 6157 IS valueIS; 6158 const PetscInt *values; 6159 PetscInt numValues, val; 6160 6161 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6162 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6163 if (isDepth) continue; 6164 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6165 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6166 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6167 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6168 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6169 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6170 for (val = 0; val < numValues; ++val) { 6171 IS pointIS; 6172 const PetscInt *points; 6173 PetscInt numPoints, n; 6174 6175 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6176 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6177 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6178 for (n = 0; n < numPoints; ++n) { 6179 const PetscInt p = points[n]; 6180 switch (refiner) { 6181 case 1: 6182 /* Simplicial 2D */ 6183 if ((p >= vStart) && (p < vEnd)) { 6184 /* Old vertices stay the same */ 6185 newp = vStartNew + (p - vStart); 6186 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6187 } else if ((p >= fStart) && (p < fEnd)) { 6188 /* Old faces add new faces and vertex */ 6189 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6190 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6191 for (r = 0; r < 2; ++r) { 6192 newp = fStartNew + (p - fStart)*2 + r; 6193 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6194 } 6195 } else if ((p >= cStart) && (p < cEnd)) { 6196 /* Old cells add new cells and interior faces */ 6197 for (r = 0; r < 4; ++r) { 6198 newp = cStartNew + (p - cStart)*4 + r; 6199 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6200 } 6201 for (r = 0; r < 3; ++r) { 6202 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6203 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6204 } 6205 } 6206 break; 6207 case 2: 6208 /* Hex 2D */ 6209 if ((p >= vStart) && (p < vEnd)) { 6210 /* Old vertices stay the same */ 6211 newp = vStartNew + (p - vStart); 6212 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6213 } else if ((p >= fStart) && (p < fEnd)) { 6214 /* Old faces add new faces and vertex */ 6215 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6216 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6217 for (r = 0; r < 2; ++r) { 6218 newp = fStartNew + (p - fStart)*2 + r; 6219 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6220 } 6221 } else if ((p >= cStart) && (p < cEnd)) { 6222 /* Old cells add new cells and interior faces and vertex */ 6223 for (r = 0; r < 4; ++r) { 6224 newp = cStartNew + (p - cStart)*4 + r; 6225 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6226 } 6227 for (r = 0; r < 4; ++r) { 6228 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6229 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6230 } 6231 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6232 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6233 } 6234 break; 6235 case 3: 6236 /* Hybrid simplicial 2D */ 6237 if ((p >= vStart) && (p < vEnd)) { 6238 /* Old vertices stay the same */ 6239 newp = vStartNew + (p - vStart); 6240 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6241 } else if ((p >= fStart) && (p < fMax)) { 6242 /* Old interior faces add new faces and vertex */ 6243 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6244 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6245 for (r = 0; r < 2; ++r) { 6246 newp = fStartNew + (p - fStart)*2 + r; 6247 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6248 } 6249 } else if ((p >= fMax) && (p < fEnd)) { 6250 /* Old hybrid faces stay the same */ 6251 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6252 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6253 } else if ((p >= cStart) && (p < cMax)) { 6254 /* Old interior cells add new cells and interior faces */ 6255 for (r = 0; r < 4; ++r) { 6256 newp = cStartNew + (p - cStart)*4 + r; 6257 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6258 } 6259 for (r = 0; r < 3; ++r) { 6260 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6261 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6262 } 6263 } else if ((p >= cMax) && (p < cEnd)) { 6264 /* Old hybrid cells add new cells and hybrid face */ 6265 for (r = 0; r < 2; ++r) { 6266 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6267 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6268 } 6269 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6270 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6271 } 6272 break; 6273 case 4: 6274 /* Hybrid Hex 2D */ 6275 if ((p >= vStart) && (p < vEnd)) { 6276 /* Old vertices stay the same */ 6277 newp = vStartNew + (p - vStart); 6278 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6279 } else if ((p >= fStart) && (p < fMax)) { 6280 /* Old interior faces add new faces and vertex */ 6281 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6282 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6283 for (r = 0; r < 2; ++r) { 6284 newp = fStartNew + (p - fStart)*2 + r; 6285 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6286 } 6287 } else if ((p >= fMax) && (p < fEnd)) { 6288 /* Old hybrid faces stay the same */ 6289 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6290 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6291 } else if ((p >= cStart) && (p < cMax)) { 6292 /* Old interior cells add new cells, interior faces, and vertex */ 6293 for (r = 0; r < 4; ++r) { 6294 newp = cStartNew + (p - cStart)*4 + r; 6295 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6296 } 6297 for (r = 0; r < 4; ++r) { 6298 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6299 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6300 } 6301 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6302 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6303 } else if ((p >= cMax) && (p < cEnd)) { 6304 /* Old hybrid cells add new cells and hybrid face */ 6305 for (r = 0; r < 2; ++r) { 6306 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6307 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6308 } 6309 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6310 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6311 } 6312 break; 6313 case 5: 6314 /* Simplicial 3D */ 6315 if ((p >= vStart) && (p < vEnd)) { 6316 /* Old vertices stay the same */ 6317 newp = vStartNew + (p - vStart); 6318 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6319 } else if ((p >= eStart) && (p < eEnd)) { 6320 /* Old edges add new edges and vertex */ 6321 for (r = 0; r < 2; ++r) { 6322 newp = eStartNew + (p - eStart)*2 + r; 6323 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6324 } 6325 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6326 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6327 } else if ((p >= fStart) && (p < fEnd)) { 6328 /* Old faces add new faces and edges */ 6329 for (r = 0; r < 4; ++r) { 6330 newp = fStartNew + (p - fStart)*4 + r; 6331 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6332 } 6333 for (r = 0; r < 3; ++r) { 6334 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6335 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6336 } 6337 } else if ((p >= cStart) && (p < cEnd)) { 6338 /* Old cells add new cells and interior faces and edges */ 6339 for (r = 0; r < 8; ++r) { 6340 newp = cStartNew + (p - cStart)*8 + r; 6341 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6342 } 6343 for (r = 0; r < 8; ++r) { 6344 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6345 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6346 } 6347 for (r = 0; r < 1; ++r) { 6348 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6349 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6350 } 6351 } 6352 break; 6353 case 7: 6354 /* Hybrid Simplicial 3D */ 6355 if ((p >= vStart) && (p < vEnd)) { 6356 /* Interior vertices stay the same */ 6357 newp = vStartNew + (p - vStart); 6358 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6359 } else if ((p >= eStart) && (p < eMax)) { 6360 /* Interior edges add new edges and vertex */ 6361 for (r = 0; r < 2; ++r) { 6362 newp = eStartNew + (p - eStart)*2 + r; 6363 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6364 } 6365 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6366 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6367 } else if ((p >= eMax) && (p < eEnd)) { 6368 /* Hybrid edges stay the same */ 6369 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6370 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6371 } else if ((p >= fStart) && (p < fMax)) { 6372 /* Interior faces add new faces and edges */ 6373 for (r = 0; r < 4; ++r) { 6374 newp = fStartNew + (p - fStart)*4 + r; 6375 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6376 } 6377 for (r = 0; r < 3; ++r) { 6378 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6379 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6380 } 6381 } else if ((p >= fMax) && (p < fEnd)) { 6382 /* Hybrid faces add new faces and edges */ 6383 for (r = 0; r < 2; ++r) { 6384 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6385 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6386 } 6387 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6388 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6389 } else if ((p >= cStart) && (p < cMax)) { 6390 /* Interior cells add new cells, faces, and edges */ 6391 for (r = 0; r < 8; ++r) { 6392 newp = cStartNew + (p - cStart)*8 + r; 6393 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6394 } 6395 for (r = 0; r < 8; ++r) { 6396 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6397 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6398 } 6399 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6400 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6401 } else if ((p >= cMax) && (p < cEnd)) { 6402 /* Hybrid cells add new cells and faces */ 6403 for (r = 0; r < 4; ++r) { 6404 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6405 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6406 } 6407 for (r = 0; r < 3; ++r) { 6408 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6409 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6410 } 6411 } 6412 break; 6413 case 6: 6414 /* Hex 3D */ 6415 if ((p >= vStart) && (p < vEnd)) { 6416 /* Old vertices stay the same */ 6417 newp = vStartNew + (p - vStart); 6418 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6419 } else if ((p >= eStart) && (p < eEnd)) { 6420 /* Old edges add new edges and vertex */ 6421 for (r = 0; r < 2; ++r) { 6422 newp = eStartNew + (p - eStart)*2 + r; 6423 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6424 } 6425 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6426 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6427 } else if ((p >= fStart) && (p < fEnd)) { 6428 /* Old faces add new faces, edges, and vertex */ 6429 for (r = 0; r < 4; ++r) { 6430 newp = fStartNew + (p - fStart)*4 + r; 6431 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6432 } 6433 for (r = 0; r < 4; ++r) { 6434 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6435 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6436 } 6437 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6438 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6439 } else if ((p >= cStart) && (p < cEnd)) { 6440 /* Old cells add new cells, faces, edges, and vertex */ 6441 for (r = 0; r < 8; ++r) { 6442 newp = cStartNew + (p - cStart)*8 + r; 6443 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6444 } 6445 for (r = 0; r < 12; ++r) { 6446 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6447 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6448 } 6449 for (r = 0; r < 6; ++r) { 6450 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6451 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6452 } 6453 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6454 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6455 } 6456 break; 6457 case 8: 6458 /* Hybrid Hex 3D */ 6459 if ((p >= vStart) && (p < vEnd)) { 6460 /* Interior vertices stay the same */ 6461 newp = vStartNew + (p - vStart); 6462 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6463 } else if ((p >= eStart) && (p < eMax)) { 6464 /* Interior edges add new edges and vertex */ 6465 for (r = 0; r < 2; ++r) { 6466 newp = eStartNew + (p - eStart)*2 + r; 6467 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6468 } 6469 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6470 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6471 } else if ((p >= eMax) && (p < eEnd)) { 6472 /* Hybrid edges stay the same */ 6473 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6474 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6475 } else if ((p >= fStart) && (p < fMax)) { 6476 /* Interior faces add new faces, edges, and vertex */ 6477 for (r = 0; r < 4; ++r) { 6478 newp = fStartNew + (p - fStart)*4 + r; 6479 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6480 } 6481 for (r = 0; r < 4; ++r) { 6482 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6483 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6484 } 6485 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6486 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6487 } else if ((p >= fMax) && (p < fEnd)) { 6488 /* Hybrid faces add new faces and edges */ 6489 for (r = 0; r < 2; ++r) { 6490 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6491 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6492 } 6493 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6494 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6495 } else if ((p >= cStart) && (p < cMax)) { 6496 /* Interior cells add new cells, faces, edges, and vertex */ 6497 for (r = 0; r < 8; ++r) { 6498 newp = cStartNew + (p - cStart)*8 + r; 6499 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6500 } 6501 for (r = 0; r < 12; ++r) { 6502 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6503 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6504 } 6505 for (r = 0; r < 6; ++r) { 6506 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6507 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6508 } 6509 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6511 } else if ((p >= cMax) && (p < cEnd)) { 6512 /* Hybrid cells add new cells, faces, and edges */ 6513 for (r = 0; r < 4; ++r) { 6514 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6515 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6516 } 6517 for (r = 0; r < 4; ++r) { 6518 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6519 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6520 } 6521 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6522 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6523 } 6524 break; 6525 default: 6526 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6527 } 6528 } 6529 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6530 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6531 } 6532 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6533 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6534 if (0) { 6535 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6536 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6537 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6538 } 6539 } 6540 PetscFunctionReturn(0); 6541 } 6542 6543 #undef __FUNCT__ 6544 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6545 /* This will only work for interpolated meshes */ 6546 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6547 { 6548 DM rdm; 6549 PetscInt *depthSize; 6550 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6551 PetscErrorCode ierr; 6552 6553 PetscFunctionBegin; 6554 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6555 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6556 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6557 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 6558 /* Calculate number of new points of each depth */ 6559 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6560 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6561 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6562 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6563 /* Step 1: Set chart */ 6564 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6565 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6566 /* Step 2: Set cone/support sizes */ 6567 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6568 /* Step 3: Setup refined DM */ 6569 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6570 /* Step 4: Set cones and supports */ 6571 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6572 /* Step 5: Stratify */ 6573 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6574 /* Step 6: Set coordinates for vertices */ 6575 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6576 /* Step 7: Create pointSF */ 6577 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6578 /* Step 8: Create labels */ 6579 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6580 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6581 6582 *dmRefined = rdm; 6583 PetscFunctionReturn(0); 6584 } 6585 6586 #undef __FUNCT__ 6587 #define __FUNCT__ "DMPlexSetRefinementUniform" 6588 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6589 { 6590 DM_Plex *mesh = (DM_Plex*) dm->data; 6591 6592 PetscFunctionBegin; 6593 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6594 mesh->refinementUniform = refinementUniform; 6595 PetscFunctionReturn(0); 6596 } 6597 6598 #undef __FUNCT__ 6599 #define __FUNCT__ "DMPlexGetRefinementUniform" 6600 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6601 { 6602 DM_Plex *mesh = (DM_Plex*) dm->data; 6603 6604 PetscFunctionBegin; 6605 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6606 PetscValidPointer(refinementUniform, 2); 6607 *refinementUniform = mesh->refinementUniform; 6608 PetscFunctionReturn(0); 6609 } 6610 6611 #undef __FUNCT__ 6612 #define __FUNCT__ "DMPlexSetRefinementLimit" 6613 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6614 { 6615 DM_Plex *mesh = (DM_Plex*) dm->data; 6616 6617 PetscFunctionBegin; 6618 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6619 mesh->refinementLimit = refinementLimit; 6620 PetscFunctionReturn(0); 6621 } 6622 6623 #undef __FUNCT__ 6624 #define __FUNCT__ "DMPlexGetRefinementLimit" 6625 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6626 { 6627 DM_Plex *mesh = (DM_Plex*) dm->data; 6628 6629 PetscFunctionBegin; 6630 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6631 PetscValidPointer(refinementLimit, 2); 6632 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6633 *refinementLimit = mesh->refinementLimit; 6634 PetscFunctionReturn(0); 6635 } 6636 6637 #undef __FUNCT__ 6638 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6639 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6640 { 6641 PetscInt dim, cStart, cEnd, coneSize, cMax; 6642 PetscErrorCode ierr; 6643 6644 PetscFunctionBegin; 6645 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6646 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6647 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 6648 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6649 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6650 switch (dim) { 6651 case 2: 6652 switch (coneSize) { 6653 case 3: 6654 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 6655 else *cellRefiner = 1; /* Triangular */ 6656 break; 6657 case 4: 6658 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 6659 else *cellRefiner = 2; /* Quadrilateral */ 6660 break; 6661 default: 6662 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6663 } 6664 break; 6665 case 3: 6666 switch (coneSize) { 6667 case 4: 6668 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 6669 else *cellRefiner = 5; /* Tetrahedral */ 6670 break; 6671 case 6: 6672 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 6673 else *cellRefiner = 6; /* hexahedral */ 6674 break; 6675 default: 6676 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6677 } 6678 break; 6679 default: 6680 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6681 } 6682 PetscFunctionReturn(0); 6683 } 6684