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__ "CellRefinerGetAffineTransforms_Internal" 30 /* Gets the affine map from the original cell to each subcell */ 31 PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 32 { 33 PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ; 34 PetscInt dim, s; 35 PetscErrorCode ierr; 36 37 PetscFunctionBegin; 38 switch (refiner) { 39 case 0: break; 40 case 1: 41 dim = 2; 42 if (numSubcells) *numSubcells = 4; 43 if (v0) { 44 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 45 /* A */ 46 v[0+0] = -1.0; v[0+1] = -1.0; 47 j[0+0] = 0.5; j[0+1] = 0.0; 48 j[0+2] = 0.0; j[0+3] = 0.5; 49 /* B */ 50 v[2+0] = 0.0; v[2+1] = -1.0; 51 j[4+0] = 0.5; j[4+1] = 0.0; 52 j[4+2] = 0.0; j[4+3] = 0.5; 53 /* C */ 54 v[4+0] = -1.0; v[4+1] = 0.0; 55 j[8+0] = 0.5; j[8+1] = 0.0; 56 j[8+2] = 0.0; j[8+3] = 0.5; 57 /* D */ 58 v[6+0] = 0.0; v[6+1] = -1.0; 59 j[12+0] = 0.0; j[12+1] = -0.5; 60 j[12+2] = 0.5; j[12+3] = 0.5; 61 for (s = 0; s < 4; ++s) { 62 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 63 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 64 } 65 } 66 break; 67 default: 68 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 69 } 70 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 71 PetscFunctionReturn(0); 72 } 73 74 #undef __FUNCT__ 75 #define __FUNCT__ "CellRefinerRestoreAffineTransforms_Internal" 76 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 77 { 78 PetscErrorCode ierr; 79 80 PetscFunctionBegin; 81 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 82 PetscFunctionReturn(0); 83 } 84 85 #undef __FUNCT__ 86 #define __FUNCT__ "CellRefinerGetSizes" 87 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 88 { 89 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 90 PetscErrorCode ierr; 91 92 PetscFunctionBegin; 93 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 94 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 95 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 96 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 97 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 98 switch (refiner) { 99 case 0: 100 break; 101 case 1: 102 /* Simplicial 2D */ 103 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 104 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 105 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 106 break; 107 case 3: 108 /* Hybrid Simplicial 2D */ 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 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 112 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 */ 113 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 114 break; 115 case 2: 116 /* Hex 2D */ 117 depthSize[0] = vEnd - vStart + cEnd - cStart + fEnd - fStart; /* Add a vertex on every face and cell */ 118 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 119 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 120 break; 121 case 5: 122 /* Simplicial 3D */ 123 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 124 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 */ 125 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 126 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 127 break; 128 case 7: 129 /* Hybrid Simplicial 3D */ 130 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 131 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 132 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 133 /* Tetrahedra */ 134 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 135 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 */ 136 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 137 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 138 /* Triangular Prisms */ 139 depthSize[0] += 0; /* No hybrid vertices */ 140 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 141 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 142 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 143 break; 144 case 6: 145 /* Hex 3D */ 146 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 147 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 */ 148 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 149 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 150 break; 151 case 8: 152 /* Hybrid Hex 3D */ 153 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 154 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 155 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 156 /* Hexahedra */ 157 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 158 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 */ 159 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 160 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 161 /* Quadrilateral Prisms */ 162 depthSize[0] += 0; /* No hybrid vertices */ 163 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 164 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 165 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 166 break; 167 default: 168 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 169 } 170 PetscFunctionReturn(0); 171 } 172 173 /* Return triangle edge for orientation o, if it is r for o == 0 */ 174 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 175 return (o < 0 ? 2-(o+r) : o+r)%3; 176 } 177 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 178 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 179 } 180 181 /* Return triangle subface for orientation o, if it is r for o == 0 */ 182 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 183 return (o < 0 ? 3-(o+r) : o+r)%3; 184 } 185 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 186 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 187 } 188 189 /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */ 190 PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) { 191 return (o < 0 ? 1-(o+r) : o+r)%3; 192 } 193 PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) { 194 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 195 } 196 197 198 /* Return quad edge for orientation o, if it is r for o == 0 */ 199 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 200 return (o < 0 ? 3-(o+r) : o+r)%4; 201 } 202 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 203 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 204 } 205 206 /* Return quad subface for orientation o, if it is r for o == 0 */ 207 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 208 return (o < 0 ? 4-(o+r) : o+r)%4; 209 } 210 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 211 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 212 } 213 214 #undef __FUNCT__ 215 #define __FUNCT__ "CellRefinerSetConeSizes" 216 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 217 { 218 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 219 PetscErrorCode ierr; 220 221 PetscFunctionBegin; 222 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 223 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 224 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 225 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 226 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 227 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 228 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 229 switch (refiner) { 230 case 0: break; 231 case 1: 232 /* Simplicial 2D */ 233 /* All cells have 3 faces */ 234 for (c = cStart; c < cEnd; ++c) { 235 for (r = 0; r < 4; ++r) { 236 const PetscInt newp = (c - cStart)*4 + r; 237 238 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 239 } 240 } 241 /* Split faces have 2 vertices and the same cells as the parent */ 242 for (f = fStart; f < fEnd; ++f) { 243 for (r = 0; r < 2; ++r) { 244 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 245 PetscInt size; 246 247 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 248 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 249 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 250 } 251 } 252 /* Interior faces have 2 vertices and 2 cells */ 253 for (c = cStart; c < cEnd; ++c) { 254 for (r = 0; r < 3; ++r) { 255 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 256 257 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 258 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 259 } 260 } 261 /* Old vertices have identical supports */ 262 for (v = vStart; v < vEnd; ++v) { 263 const PetscInt newp = vStartNew + (v - vStart); 264 PetscInt size; 265 266 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 267 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 268 } 269 /* Face vertices have 2 + cells*2 supports */ 270 for (f = fStart; f < fEnd; ++f) { 271 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 272 PetscInt size; 273 274 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 275 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 276 } 277 break; 278 case 2: 279 /* Hex 2D */ 280 /* All cells have 4 faces */ 281 for (c = cStart; c < cEnd; ++c) { 282 for (r = 0; r < 4; ++r) { 283 const PetscInt newp = (c - cStart)*4 + r; 284 285 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 286 } 287 } 288 /* Split faces have 2 vertices and the same cells as the parent */ 289 for (f = fStart; f < fEnd; ++f) { 290 for (r = 0; r < 2; ++r) { 291 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 292 PetscInt size; 293 294 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 295 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 296 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 297 } 298 } 299 /* Interior faces have 2 vertices and 2 cells */ 300 for (c = cStart; c < cEnd; ++c) { 301 for (r = 0; r < 4; ++r) { 302 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 303 304 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 305 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 306 } 307 } 308 /* Old vertices have identical supports */ 309 for (v = vStart; v < vEnd; ++v) { 310 const PetscInt newp = vStartNew + (v - vStart); 311 PetscInt size; 312 313 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 314 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 315 } 316 /* Face vertices have 2 + cells supports */ 317 for (f = fStart; f < fEnd; ++f) { 318 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 319 PetscInt size; 320 321 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 322 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 323 } 324 /* Cell vertices have 4 supports */ 325 for (c = cStart; c < cEnd; ++c) { 326 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 327 328 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 329 } 330 break; 331 case 3: 332 /* Hybrid Simplicial 2D */ 333 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 334 cMax = PetscMin(cEnd, cMax); 335 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 336 fMax = PetscMin(fEnd, fMax); 337 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 338 /* Interior cells have 3 faces */ 339 for (c = cStart; c < cMax; ++c) { 340 for (r = 0; r < 4; ++r) { 341 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 342 343 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 344 } 345 } 346 /* Hybrid cells have 4 faces */ 347 for (c = cMax; c < cEnd; ++c) { 348 for (r = 0; r < 2; ++r) { 349 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 350 351 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 352 } 353 } 354 /* Interior split faces have 2 vertices and the same cells as the parent */ 355 for (f = fStart; f < fMax; ++f) { 356 for (r = 0; r < 2; ++r) { 357 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 358 PetscInt size; 359 360 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 361 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 362 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 363 } 364 } 365 /* Interior cell faces have 2 vertices and 2 cells */ 366 for (c = cStart; c < cMax; ++c) { 367 for (r = 0; r < 3; ++r) { 368 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 369 370 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 371 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 372 } 373 } 374 /* Hybrid faces have 2 vertices and the same cells */ 375 for (f = fMax; f < fEnd; ++f) { 376 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 377 PetscInt size; 378 379 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 380 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 381 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 382 } 383 /* Hybrid cell faces have 2 vertices and 2 cells */ 384 for (c = cMax; c < cEnd; ++c) { 385 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 386 387 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 388 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 389 } 390 /* Old vertices have identical supports */ 391 for (v = vStart; v < vEnd; ++v) { 392 const PetscInt newp = vStartNew + (v - vStart); 393 PetscInt size; 394 395 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 396 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 397 } 398 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 399 for (f = fStart; f < fMax; ++f) { 400 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 401 const PetscInt *support; 402 PetscInt size, newSize = 2, s; 403 404 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 405 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 406 for (s = 0; s < size; ++s) { 407 if (support[s] >= cMax) newSize += 1; 408 else newSize += 2; 409 } 410 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 411 } 412 break; 413 case 5: 414 /* Simplicial 3D */ 415 /* All cells have 4 faces */ 416 for (c = cStart; c < cEnd; ++c) { 417 for (r = 0; r < 8; ++r) { 418 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 419 420 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 421 } 422 } 423 /* Split faces have 3 edges and the same cells as the parent */ 424 for (f = fStart; f < fEnd; ++f) { 425 for (r = 0; r < 4; ++r) { 426 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 427 PetscInt size; 428 429 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 430 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 431 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 432 } 433 } 434 /* Interior cell faces have 3 edges and 2 cells */ 435 for (c = cStart; c < cEnd; ++c) { 436 for (r = 0; r < 8; ++r) { 437 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 438 439 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 440 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 441 } 442 } 443 /* Split edges have 2 vertices and the same faces */ 444 for (e = eStart; e < eEnd; ++e) { 445 for (r = 0; r < 2; ++r) { 446 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 447 PetscInt size; 448 449 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 450 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 451 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 452 } 453 } 454 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 455 for (f = fStart; f < fEnd; ++f) { 456 for (r = 0; r < 3; ++r) { 457 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 458 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 459 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 460 461 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 462 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 463 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 464 for (s = 0; s < supportSize; ++s) { 465 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 466 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 467 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 468 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 469 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 470 er = GetTetSomethingInverse_Static(ornt[c], r); 471 if (er == eint[c]) { 472 intFaces += 1; 473 } else { 474 intFaces += 2; 475 } 476 } 477 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 478 } 479 } 480 /* Interior cell edges have 2 vertices and 4 faces */ 481 for (c = cStart; c < cEnd; ++c) { 482 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 483 484 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 485 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 486 } 487 /* Old vertices have identical supports */ 488 for (v = vStart; v < vEnd; ++v) { 489 const PetscInt newp = vStartNew + (v - vStart); 490 PetscInt size; 491 492 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 493 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 494 } 495 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 496 for (e = eStart; e < eEnd; ++e) { 497 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 498 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 499 500 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 501 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 502 for (s = 0; s < starSize*2; s += 2) { 503 const PetscInt *cone, *ornt; 504 PetscInt e01, e23; 505 506 if ((star[s] >= cStart) && (star[s] < cEnd)) { 507 /* Check edge 0-1 */ 508 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 509 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 510 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 511 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 512 /* Check edge 2-3 */ 513 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 514 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 515 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 516 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 517 if ((e01 == e) || (e23 == e)) ++cellSize; 518 } 519 } 520 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 521 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 522 } 523 break; 524 case 7: 525 /* Hybrid Simplicial 3D */ 526 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 527 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 528 /* Interior cells have 4 faces */ 529 for (c = cStart; c < cMax; ++c) { 530 for (r = 0; r < 8; ++r) { 531 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 532 533 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 534 } 535 } 536 /* Hybrid cells have 5 faces */ 537 for (c = cMax; c < cEnd; ++c) { 538 for (r = 0; r < 4; ++r) { 539 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 540 541 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 542 } 543 } 544 /* Interior split faces have 3 edges and the same cells as the parent */ 545 for (f = fStart; f < fMax; ++f) { 546 for (r = 0; r < 4; ++r) { 547 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 548 PetscInt size; 549 550 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 551 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 552 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 553 } 554 } 555 /* Interior cell faces have 3 edges and 2 cells */ 556 for (c = cStart; c < cMax; ++c) { 557 for (r = 0; r < 8; ++r) { 558 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 559 560 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 561 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 562 } 563 } 564 /* Hybrid split faces have 4 edges and the same cells as the parent */ 565 for (f = fMax; f < fEnd; ++f) { 566 for (r = 0; r < 2; ++r) { 567 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 568 PetscInt size; 569 570 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 571 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 572 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 573 } 574 } 575 /* Hybrid cells faces have 4 edges and 2 cells */ 576 for (c = cMax; c < cEnd; ++c) { 577 for (r = 0; r < 3; ++r) { 578 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 579 580 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 581 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 582 } 583 } 584 /* Interior split edges have 2 vertices and the same faces */ 585 for (e = eStart; e < eMax; ++e) { 586 for (r = 0; r < 2; ++r) { 587 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 588 PetscInt size; 589 590 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 591 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 592 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 593 } 594 } 595 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 596 for (f = fStart; f < fMax; ++f) { 597 for (r = 0; r < 3; ++r) { 598 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 599 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 600 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 601 602 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 603 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 604 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 605 for (s = 0; s < supportSize; ++s) { 606 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 607 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 608 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 609 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 610 if (support[s] < cMax) { 611 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 612 er = GetTetSomethingInverse_Static(ornt[c], r); 613 if (er == eint[c]) { 614 intFaces += 1; 615 } else { 616 intFaces += 2; 617 } 618 } else { 619 intFaces += 1; 620 } 621 } 622 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 623 } 624 } 625 /* Interior cell edges have 2 vertices and 4 faces */ 626 for (c = cStart; c < cMax; ++c) { 627 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 628 629 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 630 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 631 } 632 /* Hybrid edges have 2 vertices and the same faces */ 633 for (e = eMax; e < eEnd; ++e) { 634 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 635 PetscInt size; 636 637 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 638 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 639 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 640 } 641 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 642 for (f = fMax; f < fEnd; ++f) { 643 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 644 PetscInt size; 645 646 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 647 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 648 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 649 } 650 /* Interior vertices have identical supports */ 651 for (v = vStart; v < vEnd; ++v) { 652 const PetscInt newp = vStartNew + (v - vStart); 653 PetscInt size; 654 655 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 656 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 657 } 658 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 659 for (e = eStart; e < eMax; ++e) { 660 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 661 const PetscInt *support; 662 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 663 664 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 665 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 666 for (s = 0; s < size; ++s) { 667 if (support[s] < fMax) faceSize += 2; 668 else faceSize += 1; 669 } 670 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 671 for (s = 0; s < starSize*2; s += 2) { 672 const PetscInt *cone, *ornt; 673 PetscInt e01, e23; 674 675 if ((star[s] >= cStart) && (star[s] < cMax)) { 676 /* Check edge 0-1 */ 677 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 678 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 679 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 680 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 681 /* Check edge 2-3 */ 682 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 683 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 684 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 685 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 686 if ((e01 == e) || (e23 == e)) ++cellSize; 687 } 688 } 689 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 690 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 691 } 692 break; 693 case 6: 694 /* Hex 3D */ 695 /* All cells have 6 faces */ 696 for (c = cStart; c < cEnd; ++c) { 697 for (r = 0; r < 8; ++r) { 698 const PetscInt newp = (c - cStart)*8 + r; 699 700 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 701 } 702 } 703 /* Split faces have 4 edges and the same cells as the parent */ 704 for (f = fStart; f < fEnd; ++f) { 705 for (r = 0; r < 4; ++r) { 706 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 707 PetscInt size; 708 709 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 710 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 711 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 712 } 713 } 714 /* Interior faces have 4 edges and 2 cells */ 715 for (c = cStart; c < cEnd; ++c) { 716 for (r = 0; r < 12; ++r) { 717 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 718 719 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 720 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 721 } 722 } 723 /* Split edges have 2 vertices and the same faces as the parent */ 724 for (e = eStart; e < eEnd; ++e) { 725 for (r = 0; r < 2; ++r) { 726 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 727 PetscInt size; 728 729 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 730 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 731 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 732 } 733 } 734 /* Face edges have 2 vertices and 2+cells faces */ 735 for (f = fStart; f < fEnd; ++f) { 736 for (r = 0; r < 4; ++r) { 737 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 738 PetscInt size; 739 740 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 741 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 742 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 743 } 744 } 745 /* Cell edges have 2 vertices and 4 faces */ 746 for (c = cStart; c < cEnd; ++c) { 747 for (r = 0; r < 6; ++r) { 748 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 749 750 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 751 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 752 } 753 } 754 /* Old vertices have identical supports */ 755 for (v = vStart; v < vEnd; ++v) { 756 const PetscInt newp = vStartNew + (v - vStart); 757 PetscInt size; 758 759 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 760 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 761 } 762 /* Edge vertices have 2 + faces supports */ 763 for (e = eStart; e < eEnd; ++e) { 764 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 765 PetscInt size; 766 767 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 768 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 769 } 770 /* Face vertices have 4 + cells supports */ 771 for (f = fStart; f < fEnd; ++f) { 772 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 773 PetscInt size; 774 775 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 776 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 777 } 778 /* Cell vertices have 6 supports */ 779 for (c = cStart; c < cEnd; ++c) { 780 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 781 782 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 783 } 784 break; 785 case 8: 786 /* Hybrid Hex 3D */ 787 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 788 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 789 /* Interior cells have 6 faces */ 790 for (c = cStart; c < cMax; ++c) { 791 for (r = 0; r < 8; ++r) { 792 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 793 794 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 795 } 796 } 797 /* Hybrid cells have 6 faces */ 798 for (c = cMax; c < cEnd; ++c) { 799 for (r = 0; r < 4; ++r) { 800 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 801 802 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 803 } 804 } 805 /* Interior split faces have 4 edges and the same cells as the parent */ 806 for (f = fStart; f < fMax; ++f) { 807 for (r = 0; r < 4; ++r) { 808 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 809 PetscInt size; 810 811 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 812 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 813 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 814 } 815 } 816 /* Interior cell faces have 4 edges and 2 cells */ 817 for (c = cStart; c < cMax; ++c) { 818 for (r = 0; r < 12; ++r) { 819 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 820 821 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 822 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 823 } 824 } 825 /* Hybrid split faces have 4 edges and the same cells as the parent */ 826 for (f = fMax; f < fEnd; ++f) { 827 for (r = 0; r < 2; ++r) { 828 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 829 PetscInt size; 830 831 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 832 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 833 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 834 } 835 } 836 /* Hybrid cells faces have 4 edges and 2 cells */ 837 for (c = cMax; c < cEnd; ++c) { 838 for (r = 0; r < 4; ++r) { 839 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 840 841 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 842 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 843 } 844 } 845 /* Interior split edges have 2 vertices and the same faces as the parent */ 846 for (e = eStart; e < eMax; ++e) { 847 for (r = 0; r < 2; ++r) { 848 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 849 PetscInt size; 850 851 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 852 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 853 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 854 } 855 } 856 /* Interior face edges have 2 vertices and 2+cells faces */ 857 for (f = fStart; f < fMax; ++f) { 858 for (r = 0; r < 4; ++r) { 859 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 860 PetscInt size; 861 862 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 863 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 864 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 865 } 866 } 867 /* Interior cell edges have 2 vertices and 4 faces */ 868 for (c = cStart; c < cMax; ++c) { 869 for (r = 0; r < 6; ++r) { 870 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 871 872 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 873 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 874 } 875 } 876 /* Hybrid edges have 2 vertices and the same faces */ 877 for (e = eMax; e < eEnd; ++e) { 878 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 879 PetscInt size; 880 881 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 882 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 883 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 884 } 885 /* Hybrid face edges have 2 vertices and 2+cells faces */ 886 for (f = fMax; f < fEnd; ++f) { 887 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 888 PetscInt size; 889 890 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 891 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 892 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 893 } 894 /* Hybrid cell edges have 2 vertices and 4 faces */ 895 for (c = cMax; c < cEnd; ++c) { 896 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 897 898 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 899 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 900 } 901 /* Interior vertices have identical supports */ 902 for (v = vStart; v < vEnd; ++v) { 903 const PetscInt newp = vStartNew + (v - vStart); 904 PetscInt size; 905 906 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 907 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 908 } 909 /* Interior edge vertices have 2 + faces supports */ 910 for (e = eStart; e < eMax; ++e) { 911 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 912 PetscInt size; 913 914 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 915 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 916 } 917 /* Interior face vertices have 4 + cells supports */ 918 for (f = fStart; f < fMax; ++f) { 919 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 920 PetscInt size; 921 922 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 923 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 924 } 925 /* Interior cell vertices have 6 supports */ 926 for (c = cStart; c < cMax; ++c) { 927 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 928 929 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 930 } 931 break; 932 default: 933 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 934 } 935 PetscFunctionReturn(0); 936 } 937 938 #undef __FUNCT__ 939 #define __FUNCT__ "CellRefinerSetCones" 940 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 941 { 942 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 943 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 944 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 945 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 946 PetscErrorCode ierr; 947 948 PetscFunctionBegin; 949 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 950 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 951 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 952 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 953 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 954 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 955 if (refiner) { 956 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 957 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 958 } 959 switch (refiner) { 960 case 0: break; 961 case 1: 962 /* Simplicial 2D */ 963 /* 964 2 965 |\ 966 | \ 967 | \ 968 | \ 969 | C \ 970 | \ 971 | \ 972 2---1---1 973 |\ D / \ 974 | 2 0 \ 975 |A \ / B \ 976 0---0-------1 977 */ 978 /* All cells have 3 faces */ 979 for (c = cStart; c < cEnd; ++c) { 980 const PetscInt newp = cStartNew + (c - cStart)*4; 981 const PetscInt *cone, *ornt; 982 PetscInt coneNew[3], orntNew[3]; 983 984 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 985 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 986 /* A triangle */ 987 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 988 orntNew[0] = ornt[0]; 989 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 990 orntNew[1] = -2; 991 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 992 orntNew[2] = ornt[2]; 993 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 994 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 995 #if 1 996 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); 997 for (p = 0; p < 3; ++p) { 998 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); 999 } 1000 #endif 1001 /* B triangle */ 1002 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1003 orntNew[0] = ornt[0]; 1004 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1005 orntNew[1] = ornt[1]; 1006 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1007 orntNew[2] = -2; 1008 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1009 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1010 #if 1 1011 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); 1012 for (p = 0; p < 3; ++p) { 1013 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); 1014 } 1015 #endif 1016 /* C triangle */ 1017 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1018 orntNew[0] = -2; 1019 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1020 orntNew[1] = ornt[1]; 1021 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1022 orntNew[2] = ornt[2]; 1023 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1024 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1025 #if 1 1026 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); 1027 for (p = 0; p < 3; ++p) { 1028 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1029 } 1030 #endif 1031 /* D triangle */ 1032 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1033 orntNew[0] = 0; 1034 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1035 orntNew[1] = 0; 1036 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1037 orntNew[2] = 0; 1038 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1039 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1040 #if 1 1041 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); 1042 for (p = 0; p < 3; ++p) { 1043 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); 1044 } 1045 #endif 1046 } 1047 /* Split faces have 2 vertices and the same cells as the parent */ 1048 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1049 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1050 for (f = fStart; f < fEnd; ++f) { 1051 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1052 1053 for (r = 0; r < 2; ++r) { 1054 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1055 const PetscInt *cone, *ornt, *support; 1056 PetscInt coneNew[2], coneSize, c, supportSize, s; 1057 1058 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1059 coneNew[0] = vStartNew + (cone[0] - vStart); 1060 coneNew[1] = vStartNew + (cone[1] - vStart); 1061 coneNew[(r+1)%2] = newv; 1062 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1063 #if 1 1064 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1065 for (p = 0; p < 2; ++p) { 1066 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); 1067 } 1068 #endif 1069 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1070 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1071 for (s = 0; s < supportSize; ++s) { 1072 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1073 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1074 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1075 for (c = 0; c < coneSize; ++c) { 1076 if (cone[c] == f) break; 1077 } 1078 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1079 } 1080 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1081 #if 1 1082 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1083 for (p = 0; p < supportSize; ++p) { 1084 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); 1085 } 1086 #endif 1087 } 1088 } 1089 /* Interior faces have 2 vertices and 2 cells */ 1090 for (c = cStart; c < cEnd; ++c) { 1091 const PetscInt *cone; 1092 1093 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1094 for (r = 0; r < 3; ++r) { 1095 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1096 PetscInt coneNew[2]; 1097 PetscInt supportNew[2]; 1098 1099 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1100 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1101 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1102 #if 1 1103 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1104 for (p = 0; p < 2; ++p) { 1105 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); 1106 } 1107 #endif 1108 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1109 supportNew[1] = (c - cStart)*4 + 3; 1110 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1111 #if 1 1112 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1113 for (p = 0; p < 2; ++p) { 1114 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); 1115 } 1116 #endif 1117 } 1118 } 1119 /* Old vertices have identical supports */ 1120 for (v = vStart; v < vEnd; ++v) { 1121 const PetscInt newp = vStartNew + (v - vStart); 1122 const PetscInt *support, *cone; 1123 PetscInt size, s; 1124 1125 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1126 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1127 for (s = 0; s < size; ++s) { 1128 PetscInt r = 0; 1129 1130 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1131 if (cone[1] == v) r = 1; 1132 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1133 } 1134 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1135 #if 1 1136 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1137 for (p = 0; p < size; ++p) { 1138 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); 1139 } 1140 #endif 1141 } 1142 /* Face vertices have 2 + cells*2 supports */ 1143 for (f = fStart; f < fEnd; ++f) { 1144 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1145 const PetscInt *cone, *support; 1146 PetscInt size, s; 1147 1148 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1149 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1150 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1151 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1152 for (s = 0; s < size; ++s) { 1153 PetscInt r = 0; 1154 1155 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1156 if (cone[1] == f) r = 1; 1157 else if (cone[2] == f) r = 2; 1158 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1159 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1160 } 1161 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1162 #if 1 1163 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1164 for (p = 0; p < 2+size*2; ++p) { 1165 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); 1166 } 1167 #endif 1168 } 1169 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1170 break; 1171 case 2: 1172 /* Hex 2D */ 1173 /* 1174 3---------2---------2 1175 | | | 1176 | D 2 C | 1177 | | | 1178 3----3----0----1----1 1179 | | | 1180 | A 0 B | 1181 | | | 1182 0---------0---------1 1183 */ 1184 /* All cells have 4 faces */ 1185 for (c = cStart; c < cEnd; ++c) { 1186 const PetscInt newp = (c - cStart)*4; 1187 const PetscInt *cone, *ornt; 1188 PetscInt coneNew[4], orntNew[4]; 1189 1190 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1191 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1192 /* A quad */ 1193 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1194 orntNew[0] = ornt[0]; 1195 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1196 orntNew[1] = 0; 1197 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1198 orntNew[2] = -2; 1199 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1200 orntNew[3] = ornt[3]; 1201 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1202 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1203 #if 1 1204 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); 1205 for (p = 0; p < 4; ++p) { 1206 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); 1207 } 1208 #endif 1209 /* B quad */ 1210 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1211 orntNew[0] = ornt[0]; 1212 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1213 orntNew[1] = ornt[1]; 1214 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1215 orntNew[2] = 0; 1216 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1217 orntNew[3] = -2; 1218 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1219 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1220 #if 1 1221 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); 1222 for (p = 0; p < 4; ++p) { 1223 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); 1224 } 1225 #endif 1226 /* C quad */ 1227 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1228 orntNew[0] = -2; 1229 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1230 orntNew[1] = ornt[1]; 1231 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1232 orntNew[2] = ornt[2]; 1233 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1234 orntNew[3] = 0; 1235 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1236 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1237 #if 1 1238 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); 1239 for (p = 0; p < 4; ++p) { 1240 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); 1241 } 1242 #endif 1243 /* D quad */ 1244 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1245 orntNew[0] = 0; 1246 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1247 orntNew[1] = -2; 1248 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1249 orntNew[2] = ornt[2]; 1250 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1251 orntNew[3] = ornt[3]; 1252 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1253 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1254 #if 1 1255 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); 1256 for (p = 0; p < 4; ++p) { 1257 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); 1258 } 1259 #endif 1260 } 1261 /* Split faces have 2 vertices and the same cells as the parent */ 1262 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1263 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1264 for (f = fStart; f < fEnd; ++f) { 1265 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1266 1267 for (r = 0; r < 2; ++r) { 1268 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1269 const PetscInt *cone, *ornt, *support; 1270 PetscInt coneNew[2], coneSize, c, supportSize, s; 1271 1272 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1273 coneNew[0] = vStartNew + (cone[0] - vStart); 1274 coneNew[1] = vStartNew + (cone[1] - vStart); 1275 coneNew[(r+1)%2] = newv; 1276 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1277 #if 1 1278 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1279 for (p = 0; p < 2; ++p) { 1280 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); 1281 } 1282 #endif 1283 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1284 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1285 for (s = 0; s < supportSize; ++s) { 1286 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1287 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1288 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1289 for (c = 0; c < coneSize; ++c) { 1290 if (cone[c] == f) break; 1291 } 1292 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1293 } 1294 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1295 #if 1 1296 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1297 for (p = 0; p < supportSize; ++p) { 1298 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); 1299 } 1300 #endif 1301 } 1302 } 1303 /* Interior faces have 2 vertices and 2 cells */ 1304 for (c = cStart; c < cEnd; ++c) { 1305 const PetscInt *cone; 1306 PetscInt coneNew[2], supportNew[2]; 1307 1308 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1309 for (r = 0; r < 4; ++r) { 1310 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1311 1312 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1313 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1314 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1315 #if 1 1316 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1317 for (p = 0; p < 2; ++p) { 1318 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1319 } 1320 #endif 1321 supportNew[0] = (c - cStart)*4 + r; 1322 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1323 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1324 #if 1 1325 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1326 for (p = 0; p < 2; ++p) { 1327 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); 1328 } 1329 #endif 1330 } 1331 } 1332 /* Old vertices have identical supports */ 1333 for (v = vStart; v < vEnd; ++v) { 1334 const PetscInt newp = vStartNew + (v - vStart); 1335 const PetscInt *support, *cone; 1336 PetscInt size, s; 1337 1338 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1339 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1340 for (s = 0; s < size; ++s) { 1341 PetscInt r = 0; 1342 1343 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1344 if (cone[1] == v) r = 1; 1345 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1346 } 1347 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1348 #if 1 1349 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1350 for (p = 0; p < size; ++p) { 1351 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); 1352 } 1353 #endif 1354 } 1355 /* Face vertices have 2 + cells supports */ 1356 for (f = fStart; f < fEnd; ++f) { 1357 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1358 const PetscInt *cone, *support; 1359 PetscInt size, s; 1360 1361 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1362 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1363 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1364 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1365 for (s = 0; s < size; ++s) { 1366 PetscInt r = 0; 1367 1368 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1369 if (cone[1] == f) r = 1; 1370 else if (cone[2] == f) r = 2; 1371 else if (cone[3] == f) r = 3; 1372 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1373 } 1374 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1375 #if 1 1376 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1377 for (p = 0; p < 2+size; ++p) { 1378 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); 1379 } 1380 #endif 1381 } 1382 /* Cell vertices have 4 supports */ 1383 for (c = cStart; c < cEnd; ++c) { 1384 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1385 PetscInt supportNew[4]; 1386 1387 for (r = 0; r < 4; ++r) { 1388 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1389 } 1390 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1391 } 1392 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1393 break; 1394 case 3: 1395 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1396 cMax = PetscMin(cEnd, cMax); 1397 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1398 fMax = PetscMin(fEnd, fMax); 1399 /* Interior cells have 3 faces */ 1400 for (c = cStart; c < cMax; ++c) { 1401 const PetscInt newp = cStartNew + (c - cStart)*4; 1402 const PetscInt *cone, *ornt; 1403 PetscInt coneNew[3], orntNew[3]; 1404 1405 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1406 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1407 /* A triangle */ 1408 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1409 orntNew[0] = ornt[0]; 1410 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1411 orntNew[1] = -2; 1412 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1413 orntNew[2] = ornt[2]; 1414 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1415 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1416 #if 1 1417 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); 1418 for (p = 0; p < 3; ++p) { 1419 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); 1420 } 1421 #endif 1422 /* B triangle */ 1423 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1424 orntNew[0] = ornt[0]; 1425 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1426 orntNew[1] = ornt[1]; 1427 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1428 orntNew[2] = -2; 1429 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1430 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1431 #if 1 1432 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); 1433 for (p = 0; p < 3; ++p) { 1434 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); 1435 } 1436 #endif 1437 /* C triangle */ 1438 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1439 orntNew[0] = -2; 1440 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1441 orntNew[1] = ornt[1]; 1442 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1443 orntNew[2] = ornt[2]; 1444 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1445 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1446 #if 1 1447 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); 1448 for (p = 0; p < 3; ++p) { 1449 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); 1450 } 1451 #endif 1452 /* D triangle */ 1453 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1454 orntNew[0] = 0; 1455 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1456 orntNew[1] = 0; 1457 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1458 orntNew[2] = 0; 1459 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1460 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1461 #if 1 1462 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); 1463 for (p = 0; p < 3; ++p) { 1464 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); 1465 } 1466 #endif 1467 } 1468 /* 1469 2----3----3 1470 | | 1471 | B | 1472 | | 1473 0----4--- 1 1474 | | 1475 | A | 1476 | | 1477 0----2----1 1478 */ 1479 /* Hybrid cells have 4 faces */ 1480 for (c = cMax; c < cEnd; ++c) { 1481 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1482 const PetscInt *cone, *ornt; 1483 PetscInt coneNew[4], orntNew[4]; 1484 1485 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1486 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1487 /* A quad */ 1488 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1489 orntNew[0] = ornt[0]; 1490 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1491 orntNew[1] = ornt[1]; 1492 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2] - fMax); 1493 orntNew[2] = 0; 1494 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1495 orntNew[3] = 0; 1496 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1497 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1498 #if 1 1499 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); 1500 for (p = 0; p < 4; ++p) { 1501 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); 1502 } 1503 #endif 1504 /* B quad */ 1505 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1506 orntNew[0] = ornt[0]; 1507 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1508 orntNew[1] = ornt[1]; 1509 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1510 orntNew[2] = 0; 1511 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3] - fMax); 1512 orntNew[3] = 0; 1513 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1514 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1515 #if 1 1516 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); 1517 for (p = 0; p < 4; ++p) { 1518 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); 1519 } 1520 #endif 1521 } 1522 /* Interior split faces have 2 vertices and the same cells as the parent */ 1523 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1524 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1525 for (f = fStart; f < fMax; ++f) { 1526 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1527 1528 for (r = 0; r < 2; ++r) { 1529 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1530 const PetscInt *cone, *ornt, *support; 1531 PetscInt coneNew[2], coneSize, c, supportSize, s; 1532 1533 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1534 coneNew[0] = vStartNew + (cone[0] - vStart); 1535 coneNew[1] = vStartNew + (cone[1] - vStart); 1536 coneNew[(r+1)%2] = newv; 1537 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1538 #if 1 1539 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1540 for (p = 0; p < 2; ++p) { 1541 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); 1542 } 1543 #endif 1544 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1545 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1546 for (s = 0; s < supportSize; ++s) { 1547 if (support[s] >= cMax) { 1548 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 1549 } else { 1550 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1551 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1552 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1553 for (c = 0; c < coneSize; ++c) { 1554 if (cone[c] == f) break; 1555 } 1556 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1557 } 1558 } 1559 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1560 #if 1 1561 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1562 for (p = 0; p < supportSize; ++p) { 1563 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); 1564 } 1565 #endif 1566 } 1567 } 1568 /* Interior cell faces have 2 vertices and 2 cells */ 1569 for (c = cStart; c < cMax; ++c) { 1570 const PetscInt *cone; 1571 1572 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1573 for (r = 0; r < 3; ++r) { 1574 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1575 PetscInt coneNew[2]; 1576 PetscInt supportNew[2]; 1577 1578 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1579 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1580 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1581 #if 1 1582 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1583 for (p = 0; p < 2; ++p) { 1584 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); 1585 } 1586 #endif 1587 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1588 supportNew[1] = (c - cStart)*4 + 3; 1589 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1590 #if 1 1591 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1592 for (p = 0; p < 2; ++p) { 1593 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); 1594 } 1595 #endif 1596 } 1597 } 1598 /* Interior hybrid faces have 2 vertices and the same cells */ 1599 for (f = fMax; f < fEnd; ++f) { 1600 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1601 const PetscInt *cone; 1602 const PetscInt *support; 1603 PetscInt coneNew[2]; 1604 PetscInt supportNew[2]; 1605 PetscInt size, s, r; 1606 1607 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1608 coneNew[0] = vStartNew + (cone[0] - vStart); 1609 coneNew[1] = vStartNew + (cone[1] - vStart); 1610 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1611 #if 1 1612 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1613 for (p = 0; p < 2; ++p) { 1614 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); 1615 } 1616 #endif 1617 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1618 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1619 for (s = 0; s < size; ++s) { 1620 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1621 for (r = 0; r < 2; ++r) { 1622 if (cone[r+2] == f) break; 1623 } 1624 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 1625 } 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 < size; ++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 /* Cell hybrid faces have 2 vertices and 2 cells */ 1635 for (c = cMax; c < cEnd; ++c) { 1636 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1637 const PetscInt *cone; 1638 PetscInt coneNew[2]; 1639 PetscInt supportNew[2]; 1640 1641 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1642 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1643 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1644 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1645 #if 1 1646 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1647 for (p = 0; p < 2; ++p) { 1648 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); 1649 } 1650 #endif 1651 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1652 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1653 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1654 #if 1 1655 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1656 for (p = 0; p < 2; ++p) { 1657 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); 1658 } 1659 #endif 1660 } 1661 /* Old vertices have identical supports */ 1662 for (v = vStart; v < vEnd; ++v) { 1663 const PetscInt newp = vStartNew + (v - vStart); 1664 const PetscInt *support, *cone; 1665 PetscInt size, s; 1666 1667 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1668 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1669 for (s = 0; s < size; ++s) { 1670 if (support[s] >= fMax) { 1671 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1672 } else { 1673 PetscInt r = 0; 1674 1675 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1676 if (cone[1] == v) r = 1; 1677 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1678 } 1679 } 1680 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1681 #if 1 1682 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1683 for (p = 0; p < size; ++p) { 1684 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); 1685 } 1686 #endif 1687 } 1688 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1689 for (f = fStart; f < fMax; ++f) { 1690 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1691 const PetscInt *cone, *support; 1692 PetscInt size, newSize = 2, s; 1693 1694 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1695 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1696 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1697 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1698 for (s = 0; s < size; ++s) { 1699 PetscInt r = 0; 1700 1701 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1702 if (support[s] >= cMax) { 1703 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1704 1705 newSize += 1; 1706 } else { 1707 if (cone[1] == f) r = 1; 1708 else if (cone[2] == f) r = 2; 1709 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1710 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1711 1712 newSize += 2; 1713 } 1714 } 1715 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1716 #if 1 1717 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1718 for (p = 0; p < newSize; ++p) { 1719 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); 1720 } 1721 #endif 1722 } 1723 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1724 break; 1725 case 5: 1726 /* Simplicial 3D */ 1727 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 1728 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 1729 for (c = cStart; c < cEnd; ++c) { 1730 const PetscInt newp = cStartNew + (c - cStart)*8; 1731 const PetscInt *cone, *ornt; 1732 PetscInt coneNew[4], orntNew[4]; 1733 1734 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1735 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1736 /* A tetrahedron: {0, a, c, d} */ 1737 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 1738 orntNew[0] = ornt[0]; 1739 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 1740 orntNew[1] = ornt[1]; 1741 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 1742 orntNew[2] = ornt[2]; 1743 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 1744 orntNew[3] = 0; 1745 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1746 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1747 #if 1 1748 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); 1749 for (p = 0; p < 4; ++p) { 1750 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); 1751 } 1752 #endif 1753 /* B tetrahedron: {a, 1, b, e} */ 1754 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 1755 orntNew[0] = ornt[0]; 1756 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 1757 orntNew[1] = ornt[1]; 1758 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 1759 orntNew[2] = 0; 1760 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 1761 orntNew[3] = ornt[3]; 1762 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1763 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1764 #if 1 1765 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); 1766 for (p = 0; p < 4; ++p) { 1767 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); 1768 } 1769 #endif 1770 /* C tetrahedron: {c, b, 2, f} */ 1771 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 1772 orntNew[0] = ornt[0]; 1773 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 1774 orntNew[1] = 0; 1775 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 1776 orntNew[2] = ornt[2]; 1777 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 1778 orntNew[3] = ornt[3]; 1779 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1780 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1781 #if 1 1782 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); 1783 for (p = 0; p < 4; ++p) { 1784 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); 1785 } 1786 #endif 1787 /* D tetrahedron: {d, e, f, 3} */ 1788 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 1789 orntNew[0] = 0; 1790 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 1791 orntNew[1] = ornt[1]; 1792 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 1793 orntNew[2] = ornt[2]; 1794 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 1795 orntNew[3] = ornt[3]; 1796 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1797 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1798 #if 1 1799 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); 1800 for (p = 0; p < 4; ++p) { 1801 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); 1802 } 1803 #endif 1804 /* A' tetrahedron: {d, a, c, f} */ 1805 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 1806 orntNew[0] = -3; 1807 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 1808 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 1809 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1810 orntNew[2] = 0; 1811 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1812 orntNew[3] = 2; 1813 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 1814 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 1815 #if 1 1816 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); 1817 for (p = 0; p < 4; ++p) { 1818 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); 1819 } 1820 #endif 1821 /* B' tetrahedron: {e, b, a, f} */ 1822 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 1823 orntNew[0] = -3; 1824 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1825 orntNew[1] = 1; 1826 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1827 orntNew[2] = 0; 1828 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 1829 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 1830 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 1831 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 1832 #if 1 1833 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); 1834 for (p = 0; p < 4; ++p) { 1835 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); 1836 } 1837 #endif 1838 /* C' tetrahedron: {b, f, c, a} */ 1839 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 1840 orntNew[0] = -3; 1841 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 1842 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 1843 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 1844 orntNew[2] = -3; 1845 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 1846 orntNew[3] = -2; 1847 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 1848 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 1849 #if 1 1850 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); 1851 for (p = 0; p < 4; ++p) { 1852 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); 1853 } 1854 #endif 1855 /* D' tetrahedron: {f, e, d, a} */ 1856 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 1857 orntNew[0] = -3; 1858 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 1859 orntNew[1] = -3; 1860 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 1861 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 1862 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 1863 orntNew[3] = -3; 1864 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 1865 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 1866 #if 1 1867 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); 1868 for (p = 0; p < 4; ++p) { 1869 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); 1870 } 1871 #endif 1872 } 1873 /* Split faces have 3 edges and the same cells as the parent */ 1874 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1875 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1876 for (f = fStart; f < fEnd; ++f) { 1877 const PetscInt newp = fStartNew + (f - fStart)*4; 1878 const PetscInt *cone, *ornt, *support; 1879 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 1880 1881 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1882 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 1883 /* A triangle */ 1884 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 1885 orntNew[0] = ornt[0]; 1886 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 1887 orntNew[1] = -2; 1888 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 1889 orntNew[2] = ornt[2]; 1890 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1891 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1892 #if 1 1893 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); 1894 for (p = 0; p < 3; ++p) { 1895 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); 1896 } 1897 #endif 1898 /* B triangle */ 1899 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 1900 orntNew[0] = ornt[0]; 1901 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 1902 orntNew[1] = ornt[1]; 1903 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 1904 orntNew[2] = -2; 1905 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1906 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1907 #if 1 1908 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); 1909 for (p = 0; p < 3; ++p) { 1910 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); 1911 } 1912 #endif 1913 /* C triangle */ 1914 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 1915 orntNew[0] = -2; 1916 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 1917 orntNew[1] = ornt[1]; 1918 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 1919 orntNew[2] = ornt[2]; 1920 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1921 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1922 #if 1 1923 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); 1924 for (p = 0; p < 3; ++p) { 1925 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); 1926 } 1927 #endif 1928 /* D triangle */ 1929 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 1930 orntNew[0] = 0; 1931 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 1932 orntNew[1] = 0; 1933 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 1934 orntNew[2] = 0; 1935 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1936 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1937 #if 1 1938 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); 1939 for (p = 0; p < 3; ++p) { 1940 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); 1941 } 1942 #endif 1943 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1944 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1945 for (r = 0; r < 4; ++r) { 1946 for (s = 0; s < supportSize; ++s) { 1947 PetscInt subf; 1948 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1949 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1950 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1951 for (c = 0; c < coneSize; ++c) { 1952 if (cone[c] == f) break; 1953 } 1954 subf = GetTriSubfaceInverse_Static(ornt[c], r); 1955 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 1956 } 1957 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 1958 #if 1 1959 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); 1960 for (p = 0; p < supportSize; ++p) { 1961 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); 1962 } 1963 #endif 1964 } 1965 } 1966 /* Interior faces have 3 edges and 2 cells */ 1967 for (c = cStart; c < cEnd; ++c) { 1968 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 1969 const PetscInt *cone, *ornt; 1970 PetscInt coneNew[3], orntNew[3]; 1971 PetscInt supportNew[2]; 1972 1973 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1974 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1975 /* Face A: {c, a, d} */ 1976 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 1977 orntNew[0] = ornt[0] < 0 ? -2 : 0; 1978 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 1979 orntNew[1] = ornt[1] < 0 ? -2 : 0; 1980 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 1981 orntNew[2] = ornt[2] < 0 ? -2 : 0; 1982 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1983 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 1984 #if 1 1985 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1986 for (p = 0; p < 3; ++p) { 1987 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); 1988 } 1989 #endif 1990 supportNew[0] = (c - cStart)*8 + 0; 1991 supportNew[1] = (c - cStart)*8 + 0+4; 1992 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1993 #if 1 1994 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1995 for (p = 0; p < 2; ++p) { 1996 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); 1997 } 1998 #endif 1999 ++newp; 2000 /* Face B: {a, b, e} */ 2001 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2002 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2003 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2004 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2005 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2006 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2007 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2008 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2009 #if 1 2010 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2011 for (p = 0; p < 3; ++p) { 2012 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); 2013 } 2014 #endif 2015 supportNew[0] = (c - cStart)*8 + 1; 2016 supportNew[1] = (c - cStart)*8 + 1+4; 2017 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2018 #if 1 2019 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2020 for (p = 0; p < 2; ++p) { 2021 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); 2022 } 2023 #endif 2024 ++newp; 2025 /* Face C: {c, f, b} */ 2026 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2027 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2028 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2029 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2030 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2031 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2032 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2033 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2034 #if 1 2035 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2036 for (p = 0; p < 3; ++p) { 2037 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); 2038 } 2039 #endif 2040 supportNew[0] = (c - cStart)*8 + 2; 2041 supportNew[1] = (c - cStart)*8 + 2+4; 2042 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2043 #if 1 2044 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2045 for (p = 0; p < 2; ++p) { 2046 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); 2047 } 2048 #endif 2049 ++newp; 2050 /* Face D: {d, e, f} */ 2051 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2052 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2053 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2054 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2055 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2056 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2057 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2058 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2059 #if 1 2060 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2061 for (p = 0; p < 3; ++p) { 2062 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); 2063 } 2064 #endif 2065 supportNew[0] = (c - cStart)*8 + 3; 2066 supportNew[1] = (c - cStart)*8 + 3+4; 2067 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2068 #if 1 2069 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2070 for (p = 0; p < 2; ++p) { 2071 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); 2072 } 2073 #endif 2074 ++newp; 2075 /* Face E: {d, f, a} */ 2076 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2077 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2078 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2079 orntNew[1] = -2; 2080 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2081 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2082 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2083 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2084 #if 1 2085 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2086 for (p = 0; p < 3; ++p) { 2087 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); 2088 } 2089 #endif 2090 supportNew[0] = (c - cStart)*8 + 0+4; 2091 supportNew[1] = (c - cStart)*8 + 3+4; 2092 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2093 #if 1 2094 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2095 for (p = 0; p < 2; ++p) { 2096 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); 2097 } 2098 #endif 2099 ++newp; 2100 /* Face F: {c, a, f} */ 2101 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2102 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2103 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2104 orntNew[1] = 0; 2105 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2106 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2107 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2108 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2109 #if 1 2110 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2111 for (p = 0; p < 3; ++p) { 2112 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); 2113 } 2114 #endif 2115 supportNew[0] = (c - cStart)*8 + 0+4; 2116 supportNew[1] = (c - cStart)*8 + 2+4; 2117 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2118 #if 1 2119 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2120 for (p = 0; p < 2; ++p) { 2121 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); 2122 } 2123 #endif 2124 ++newp; 2125 /* Face G: {e, a, f} */ 2126 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2127 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2128 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2129 orntNew[1] = 0; 2130 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2131 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2132 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2133 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2134 #if 1 2135 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2136 for (p = 0; p < 3; ++p) { 2137 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); 2138 } 2139 #endif 2140 supportNew[0] = (c - cStart)*8 + 1+4; 2141 supportNew[1] = (c - cStart)*8 + 3+4; 2142 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2143 #if 1 2144 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2145 for (p = 0; p < 2; ++p) { 2146 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); 2147 } 2148 #endif 2149 ++newp; 2150 /* Face H: {a, b, f} */ 2151 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2152 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2153 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2154 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2155 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2156 orntNew[2] = -2; 2157 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2158 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2159 #if 1 2160 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2161 for (p = 0; p < 3; ++p) { 2162 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); 2163 } 2164 #endif 2165 supportNew[0] = (c - cStart)*8 + 1+4; 2166 supportNew[1] = (c - cStart)*8 + 2+4; 2167 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2168 #if 1 2169 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2170 for (p = 0; p < 2; ++p) { 2171 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); 2172 } 2173 #endif 2174 ++newp; 2175 } 2176 /* Split Edges have 2 vertices and the same faces as the parent */ 2177 for (e = eStart; e < eEnd; ++e) { 2178 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2179 2180 for (r = 0; r < 2; ++r) { 2181 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2182 const PetscInt *cone, *ornt, *support; 2183 PetscInt coneNew[2], coneSize, c, supportSize, s; 2184 2185 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2186 coneNew[0] = vStartNew + (cone[0] - vStart); 2187 coneNew[1] = vStartNew + (cone[1] - vStart); 2188 coneNew[(r+1)%2] = newv; 2189 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2190 #if 1 2191 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2192 for (p = 0; p < 2; ++p) { 2193 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); 2194 } 2195 #endif 2196 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2197 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2198 for (s = 0; s < supportSize; ++s) { 2199 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2200 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2201 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2202 for (c = 0; c < coneSize; ++c) { 2203 if (cone[c] == e) break; 2204 } 2205 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2206 } 2207 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2208 #if 1 2209 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2210 for (p = 0; p < supportSize; ++p) { 2211 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); 2212 } 2213 #endif 2214 } 2215 } 2216 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2217 for (f = fStart; f < fEnd; ++f) { 2218 const PetscInt *cone, *ornt, *support; 2219 PetscInt coneSize, supportSize, s; 2220 2221 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2222 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2223 for (r = 0; r < 3; ++r) { 2224 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2225 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2226 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2227 -1, -1, 1, 6, 0, 4, 2228 2, 5, 3, 4, -1, -1, 2229 -1, -1, 3, 6, 2, 7}; 2230 2231 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2232 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2233 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2234 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2235 #if 1 2236 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2237 for (p = 0; p < 2; ++p) { 2238 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); 2239 } 2240 #endif 2241 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2242 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2243 for (s = 0; s < supportSize; ++s) { 2244 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2245 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2246 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2247 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2248 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2249 er = GetTetSomethingInverse_Static(ornt[c], r); 2250 if (er == eint[c]) { 2251 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2252 } else { 2253 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2254 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2255 } 2256 } 2257 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2258 #if 1 2259 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2260 for (p = 0; p < intFaces; ++p) { 2261 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); 2262 } 2263 #endif 2264 } 2265 } 2266 /* Interior edges have 2 vertices and 4 faces */ 2267 for (c = cStart; c < cEnd; ++c) { 2268 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2269 const PetscInt *cone, *ornt, *fcone; 2270 PetscInt coneNew[2], supportNew[4], find; 2271 2272 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2273 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2274 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2275 find = GetTriEdge_Static(ornt[0], 0); 2276 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2277 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2278 find = GetTriEdge_Static(ornt[2], 1); 2279 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2280 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2281 #if 1 2282 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2283 for (p = 0; p < 2; ++p) { 2284 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); 2285 } 2286 #endif 2287 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2288 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2289 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2290 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2291 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2292 #if 1 2293 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2294 for (p = 0; p < 4; ++p) { 2295 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); 2296 } 2297 #endif 2298 } 2299 /* Old vertices have identical supports */ 2300 for (v = vStart; v < vEnd; ++v) { 2301 const PetscInt newp = vStartNew + (v - vStart); 2302 const PetscInt *support, *cone; 2303 PetscInt size, s; 2304 2305 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2306 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2307 for (s = 0; s < size; ++s) { 2308 PetscInt r = 0; 2309 2310 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2311 if (cone[1] == v) r = 1; 2312 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2313 } 2314 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2315 #if 1 2316 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2317 for (p = 0; p < size; ++p) { 2318 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); 2319 } 2320 #endif 2321 } 2322 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2323 for (e = eStart; e < eEnd; ++e) { 2324 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2325 const PetscInt *cone, *support; 2326 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2327 2328 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2329 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2330 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2331 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2332 for (s = 0; s < size; ++s) { 2333 PetscInt r = 0; 2334 2335 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2336 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2337 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2338 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2339 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2340 } 2341 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2342 for (s = 0; s < starSize*2; s += 2) { 2343 const PetscInt *cone, *ornt; 2344 PetscInt e01, e23; 2345 2346 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2347 /* Check edge 0-1 */ 2348 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2349 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2350 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2351 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2352 /* Check edge 2-3 */ 2353 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2354 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2355 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2356 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2357 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2358 } 2359 } 2360 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2361 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2362 #if 1 2363 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2364 for (p = 0; p < 2+size*2+cellSize; ++p) { 2365 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); 2366 } 2367 #endif 2368 } 2369 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2370 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2371 break; 2372 case 7: 2373 /* Hybrid Simplicial 3D */ 2374 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2375 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2376 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2377 for (c = cStart; c < cMax; ++c) { 2378 const PetscInt newp = cStartNew + (c - cStart)*8; 2379 const PetscInt *cone, *ornt; 2380 PetscInt coneNew[4], orntNew[4]; 2381 2382 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2383 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2384 /* A tetrahedron: {0, a, c, d} */ 2385 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2386 orntNew[0] = ornt[0]; 2387 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2388 orntNew[1] = ornt[1]; 2389 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2390 orntNew[2] = ornt[2]; 2391 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2392 orntNew[3] = 0; 2393 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2394 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2395 #if 1 2396 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); 2397 for (p = 0; p < 4; ++p) { 2398 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); 2399 } 2400 #endif 2401 /* B tetrahedron: {a, 1, b, e} */ 2402 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2403 orntNew[0] = ornt[0]; 2404 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2405 orntNew[1] = ornt[1]; 2406 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2407 orntNew[2] = 0; 2408 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2409 orntNew[3] = ornt[3]; 2410 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2411 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2412 #if 1 2413 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); 2414 for (p = 0; p < 4; ++p) { 2415 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); 2416 } 2417 #endif 2418 /* C tetrahedron: {c, b, 2, f} */ 2419 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2420 orntNew[0] = ornt[0]; 2421 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2422 orntNew[1] = 0; 2423 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2424 orntNew[2] = ornt[2]; 2425 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2426 orntNew[3] = ornt[3]; 2427 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2428 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2429 #if 1 2430 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); 2431 for (p = 0; p < 4; ++p) { 2432 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); 2433 } 2434 #endif 2435 /* D tetrahedron: {d, e, f, 3} */ 2436 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2437 orntNew[0] = 0; 2438 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2439 orntNew[1] = ornt[1]; 2440 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2441 orntNew[2] = ornt[2]; 2442 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2443 orntNew[3] = ornt[3]; 2444 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2445 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2446 #if 1 2447 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); 2448 for (p = 0; p < 4; ++p) { 2449 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); 2450 } 2451 #endif 2452 /* A' tetrahedron: {d, a, c, f} */ 2453 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2454 orntNew[0] = -3; 2455 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2456 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2457 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2458 orntNew[2] = 0; 2459 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2460 orntNew[3] = 2; 2461 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2462 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2463 #if 1 2464 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); 2465 for (p = 0; p < 4; ++p) { 2466 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); 2467 } 2468 #endif 2469 /* B' tetrahedron: {e, b, a, f} */ 2470 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2471 orntNew[0] = -3; 2472 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2473 orntNew[1] = 1; 2474 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2475 orntNew[2] = 0; 2476 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2477 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2478 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2479 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2480 #if 1 2481 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); 2482 for (p = 0; p < 4; ++p) { 2483 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); 2484 } 2485 #endif 2486 /* C' tetrahedron: {b, f, c, a} */ 2487 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2488 orntNew[0] = -3; 2489 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2490 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2491 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2492 orntNew[2] = -3; 2493 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2494 orntNew[3] = -2; 2495 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2496 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2497 #if 1 2498 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); 2499 for (p = 0; p < 4; ++p) { 2500 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); 2501 } 2502 #endif 2503 /* D' tetrahedron: {f, e, d, a} */ 2504 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2505 orntNew[0] = -3; 2506 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2507 orntNew[1] = -3; 2508 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2509 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2510 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2511 orntNew[3] = -3; 2512 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2513 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2514 #if 1 2515 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); 2516 for (p = 0; p < 4; ++p) { 2517 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); 2518 } 2519 #endif 2520 } 2521 /* Hybrid cells have 5 faces */ 2522 for (c = cMax; c < cEnd; ++c) { 2523 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 2524 const PetscInt *cone, *ornt, *fornt; 2525 PetscInt coneNew[5], orntNew[5]; 2526 2527 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2528 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2529 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 2530 for (r = 0; r < 3; ++r) { 2531 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 2532 orntNew[0] = ornt[0]; 2533 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 2534 orntNew[1] = ornt[1]; 2535 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? 0 : 1); 2536 orntNew[2] = 0; 2537 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? 1 : 0); 2538 orntNew[3] = 0; 2539 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 2540 orntNew[4] = 0; 2541 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2542 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2543 #if 1 2544 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); 2545 for (p = 0; p < 2; ++p) { 2546 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); 2547 } 2548 for (p = 2; p < 5; ++p) { 2549 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); 2550 } 2551 #endif 2552 } 2553 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 2554 orntNew[0] = 0; 2555 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 2556 orntNew[1] = 0; 2557 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 2558 orntNew[2] = 0; 2559 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 2560 orntNew[3] = 0; 2561 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 2562 orntNew[4] = 0; 2563 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2564 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2565 #if 1 2566 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); 2567 for (p = 0; p < 2; ++p) { 2568 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); 2569 } 2570 for (p = 2; p < 5; ++p) { 2571 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); 2572 } 2573 #endif 2574 } 2575 /* Split faces have 3 edges and the same cells as the parent */ 2576 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2577 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2578 for (f = fStart; f < fMax; ++f) { 2579 const PetscInt newp = fStartNew + (f - fStart)*4; 2580 const PetscInt *cone, *ornt, *support; 2581 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2582 2583 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2584 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2585 /* A triangle */ 2586 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2587 orntNew[0] = ornt[0]; 2588 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2589 orntNew[1] = -2; 2590 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2591 orntNew[2] = ornt[2]; 2592 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2593 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2594 #if 1 2595 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); 2596 for (p = 0; p < 3; ++p) { 2597 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); 2598 } 2599 #endif 2600 /* B triangle */ 2601 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2602 orntNew[0] = ornt[0]; 2603 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2604 orntNew[1] = ornt[1]; 2605 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2606 orntNew[2] = -2; 2607 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2608 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2609 #if 1 2610 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); 2611 for (p = 0; p < 3; ++p) { 2612 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 2613 } 2614 #endif 2615 /* C triangle */ 2616 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2617 orntNew[0] = -2; 2618 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2619 orntNew[1] = ornt[1]; 2620 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2621 orntNew[2] = ornt[2]; 2622 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2623 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2624 #if 1 2625 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); 2626 for (p = 0; p < 3; ++p) { 2627 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); 2628 } 2629 #endif 2630 /* D triangle */ 2631 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 2632 orntNew[0] = 0; 2633 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 2634 orntNew[1] = 0; 2635 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 2636 orntNew[2] = 0; 2637 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2638 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2639 #if 1 2640 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); 2641 for (p = 0; p < 3; ++p) { 2642 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); 2643 } 2644 #endif 2645 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2646 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2647 for (r = 0; r < 4; ++r) { 2648 for (s = 0; s < supportSize; ++s) { 2649 PetscInt subf; 2650 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2651 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2652 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2653 for (c = 0; c < coneSize; ++c) { 2654 if (cone[c] == f) break; 2655 } 2656 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2657 if (support[s] < cMax) { 2658 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2659 } else { 2660 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 2661 } 2662 } 2663 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2664 #if 1 2665 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); 2666 for (p = 0; p < supportSize; ++p) { 2667 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); 2668 } 2669 #endif 2670 } 2671 } 2672 /* Interior cell faces have 3 edges and 2 cells */ 2673 for (c = cStart; c < cMax; ++c) { 2674 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 2675 const PetscInt *cone, *ornt; 2676 PetscInt coneNew[3], orntNew[3]; 2677 PetscInt supportNew[2]; 2678 2679 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2680 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2681 /* Face A: {c, a, d} */ 2682 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2683 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2684 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2685 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2686 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2687 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2688 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2689 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2690 #if 1 2691 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2692 for (p = 0; p < 3; ++p) { 2693 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); 2694 } 2695 #endif 2696 supportNew[0] = (c - cStart)*8 + 0; 2697 supportNew[1] = (c - cStart)*8 + 0+4; 2698 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2699 #if 1 2700 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2701 for (p = 0; p < 2; ++p) { 2702 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); 2703 } 2704 #endif 2705 ++newp; 2706 /* Face B: {a, b, e} */ 2707 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2708 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2709 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2710 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2711 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2712 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2713 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2714 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2715 #if 1 2716 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); 2717 for (p = 0; p < 3; ++p) { 2718 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); 2719 } 2720 #endif 2721 supportNew[0] = (c - cStart)*8 + 1; 2722 supportNew[1] = (c - cStart)*8 + 1+4; 2723 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2724 #if 1 2725 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2726 for (p = 0; p < 2; ++p) { 2727 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); 2728 } 2729 #endif 2730 ++newp; 2731 /* Face C: {c, f, b} */ 2732 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2733 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2734 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2735 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2736 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2737 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2738 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2739 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2740 #if 1 2741 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2742 for (p = 0; p < 3; ++p) { 2743 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); 2744 } 2745 #endif 2746 supportNew[0] = (c - cStart)*8 + 2; 2747 supportNew[1] = (c - cStart)*8 + 2+4; 2748 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2749 #if 1 2750 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2751 for (p = 0; p < 2; ++p) { 2752 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); 2753 } 2754 #endif 2755 ++newp; 2756 /* Face D: {d, e, f} */ 2757 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2758 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2759 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2760 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2761 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2762 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2763 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2764 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2765 #if 1 2766 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2767 for (p = 0; p < 3; ++p) { 2768 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); 2769 } 2770 #endif 2771 supportNew[0] = (c - cStart)*8 + 3; 2772 supportNew[1] = (c - cStart)*8 + 3+4; 2773 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2774 #if 1 2775 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2776 for (p = 0; p < 2; ++p) { 2777 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); 2778 } 2779 #endif 2780 ++newp; 2781 /* Face E: {d, f, a} */ 2782 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2783 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2784 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2785 orntNew[1] = -2; 2786 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2787 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2788 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2789 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2790 #if 1 2791 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2792 for (p = 0; p < 3; ++p) { 2793 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); 2794 } 2795 #endif 2796 supportNew[0] = (c - cStart)*8 + 0+4; 2797 supportNew[1] = (c - cStart)*8 + 3+4; 2798 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2799 #if 1 2800 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2801 for (p = 0; p < 2; ++p) { 2802 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); 2803 } 2804 #endif 2805 ++newp; 2806 /* Face F: {c, a, f} */ 2807 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2808 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2809 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2810 orntNew[1] = 0; 2811 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2812 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2813 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2814 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2815 #if 1 2816 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2817 for (p = 0; p < 3; ++p) { 2818 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); 2819 } 2820 #endif 2821 supportNew[0] = (c - cStart)*8 + 0+4; 2822 supportNew[1] = (c - cStart)*8 + 2+4; 2823 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2824 #if 1 2825 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2826 for (p = 0; p < 2; ++p) { 2827 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); 2828 } 2829 #endif 2830 ++newp; 2831 /* Face G: {e, a, f} */ 2832 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2833 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2834 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2835 orntNew[1] = 0; 2836 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2837 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2838 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2839 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2840 #if 1 2841 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2842 for (p = 0; p < 3; ++p) { 2843 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); 2844 } 2845 #endif 2846 supportNew[0] = (c - cStart)*8 + 1+4; 2847 supportNew[1] = (c - cStart)*8 + 3+4; 2848 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2849 #if 1 2850 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2851 for (p = 0; p < 2; ++p) { 2852 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); 2853 } 2854 #endif 2855 ++newp; 2856 /* Face H: {a, b, f} */ 2857 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2858 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2859 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2860 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2861 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 2862 orntNew[2] = -2; 2863 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2864 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2865 #if 1 2866 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2867 for (p = 0; p < 3; ++p) { 2868 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); 2869 } 2870 #endif 2871 supportNew[0] = (c - cStart)*8 + 1+4; 2872 supportNew[1] = (c - cStart)*8 + 2+4; 2873 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2874 #if 1 2875 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 2876 for (p = 0; p < 2; ++p) { 2877 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); 2878 } 2879 #endif 2880 ++newp; 2881 } 2882 /* Hybrid split faces have 4 edges and same cells */ 2883 for (f = fMax; f < fEnd; ++f) { 2884 const PetscInt *cone, *ornt, *support; 2885 PetscInt coneNew[4], orntNew[4]; 2886 PetscInt supportNew[2], size, s, c; 2887 2888 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2889 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2890 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2891 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2892 for (r = 0; r < 2; ++r) { 2893 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 2894 2895 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 2896 orntNew[0] = ornt[0]; 2897 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 2898 orntNew[1] = ornt[1]; 2899 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 2900 orntNew[2+r] = 0; 2901 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 2902 orntNew[3-r] = 0; 2903 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2904 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2905 #if 1 2906 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2907 for (p = 0; p < 2; ++p) { 2908 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); 2909 } 2910 for (p = 2; p < 4; ++p) { 2911 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); 2912 } 2913 #endif 2914 for (s = 0; s < size; ++s) { 2915 const PetscInt *coneCell, *orntCell, *fornt; 2916 2917 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 2918 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 2919 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 2920 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 2921 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 2922 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%3; 2923 } 2924 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2925 #if 1 2926 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 2927 for (p = 0; p < size; ++p) { 2928 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); 2929 } 2930 #endif 2931 } 2932 } 2933 /* Hybrid cell faces have 4 edges and 2 cells */ 2934 for (c = cMax; c < cEnd; ++c) { 2935 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 2936 const PetscInt *cone, *ornt; 2937 PetscInt coneNew[4], orntNew[4]; 2938 PetscInt supportNew[2]; 2939 2940 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2941 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2942 for (r = 0; r < 3; ++r) { 2943 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], (r+2)%3); 2944 orntNew[0] = 0; 2945 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], (r+2)%3); 2946 orntNew[1] = 0; 2947 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], (r+2)%3)] - fMax); 2948 orntNew[2] = 0; 2949 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+GetTriSubface_Static(ornt[0], r)] - fMax); 2950 orntNew[3] = 0; 2951 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2952 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2953 #if 1 2954 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); 2955 for (p = 0; p < 2; ++p) { 2956 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); 2957 } 2958 for (p = 2; p < 4; ++p) { 2959 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); 2960 } 2961 #endif 2962 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 2963 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 2964 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 2965 #if 1 2966 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); 2967 for (p = 0; p < 2; ++p) { 2968 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); 2969 } 2970 #endif 2971 } 2972 } 2973 /* Interior split edges have 2 vertices and the same faces as the parent */ 2974 for (e = eStart; e < eMax; ++e) { 2975 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2976 2977 for (r = 0; r < 2; ++r) { 2978 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2979 const PetscInt *cone, *ornt, *support; 2980 PetscInt coneNew[2], coneSize, c, supportSize, s; 2981 2982 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2983 coneNew[0] = vStartNew + (cone[0] - vStart); 2984 coneNew[1] = vStartNew + (cone[1] - vStart); 2985 coneNew[(r+1)%2] = newv; 2986 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2987 #if 1 2988 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 2989 for (p = 0; p < 2; ++p) { 2990 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); 2991 } 2992 #endif 2993 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2994 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2995 for (s = 0; s < supportSize; ++s) { 2996 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2997 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2998 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2999 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3000 if (support[s] < fMax) { 3001 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3002 } else { 3003 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3004 } 3005 } 3006 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3007 #if 1 3008 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3009 for (p = 0; p < supportSize; ++p) { 3010 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); 3011 } 3012 #endif 3013 } 3014 } 3015 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3016 for (f = fStart; f < fMax; ++f) { 3017 const PetscInt *cone, *ornt, *support; 3018 PetscInt coneSize, supportSize, s; 3019 3020 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3021 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3022 for (r = 0; r < 3; ++r) { 3023 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3024 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3025 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3026 -1, -1, 1, 6, 0, 4, 3027 2, 5, 3, 4, -1, -1, 3028 -1, -1, 3, 6, 2, 7}; 3029 3030 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3031 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3032 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3033 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3034 #if 1 3035 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3036 for (p = 0; p < 2; ++p) { 3037 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); 3038 } 3039 #endif 3040 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3041 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3042 for (s = 0; s < supportSize; ++s) { 3043 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3044 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3045 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3046 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3047 if (support[s] < cMax) { 3048 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3049 er = GetTetSomethingInverse_Static(ornt[c], r); 3050 if (er == eint[c]) { 3051 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3052 } else { 3053 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3054 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3055 } 3056 } else { 3057 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(ornt[c], r) + 1)%3; 3058 } 3059 } 3060 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3061 #if 1 3062 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3063 for (p = 0; p < intFaces; ++p) { 3064 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); 3065 } 3066 #endif 3067 } 3068 } 3069 /* Interior cell edges have 2 vertices and 4 faces */ 3070 for (c = cStart; c < cMax; ++c) { 3071 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3072 const PetscInt *cone, *ornt, *fcone; 3073 PetscInt coneNew[2], supportNew[4], find; 3074 3075 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3076 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3077 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3078 find = GetTriEdge_Static(ornt[0], 0); 3079 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3080 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3081 find = GetTriEdge_Static(ornt[2], 1); 3082 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3083 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3084 #if 1 3085 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3086 for (p = 0; p < 2; ++p) { 3087 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); 3088 } 3089 #endif 3090 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3091 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3092 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3093 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3094 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3095 #if 1 3096 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3097 for (p = 0; p < 4; ++p) { 3098 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); 3099 } 3100 #endif 3101 } 3102 /* Hybrid edges have two vertices and the same faces */ 3103 for (e = eMax; e < eEnd; ++e) { 3104 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3105 const PetscInt *cone, *support, *fcone; 3106 PetscInt coneNew[2], size, fsize, s; 3107 3108 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3109 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3110 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3111 coneNew[0] = vStartNew + (cone[0] - vStart); 3112 coneNew[1] = vStartNew + (cone[1] - vStart); 3113 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3114 #if 1 3115 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3116 for (p = 0; p < 2; ++p) { 3117 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); 3118 } 3119 #endif 3120 for (s = 0; s < size; ++s) { 3121 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3122 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3123 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3124 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3125 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3126 } 3127 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3128 #if 1 3129 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3130 for (p = 0; p < size; ++p) { 3131 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); 3132 } 3133 #endif 3134 } 3135 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3136 for (f = fMax; f < fEnd; ++f) { 3137 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3138 const PetscInt *cone, *support, *ccone, *cornt; 3139 PetscInt coneNew[2], size, csize, s; 3140 3141 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3142 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3143 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3144 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3145 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3146 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3147 #if 1 3148 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3149 for (p = 0; p < 2; ++p) { 3150 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); 3151 } 3152 #endif 3153 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3154 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3155 for (s = 0; s < size; ++s) { 3156 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3157 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3158 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3159 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3160 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]); 3161 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + GetTriSubfaceInverse_Static(cornt[0], c-2); 3162 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (GetTriSubfaceInverse_Static(cornt[0], c-2) + 1)%3; 3163 } 3164 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3165 #if 1 3166 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3167 for (p = 0; p < 2+size*2; ++p) { 3168 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); 3169 } 3170 #endif 3171 } 3172 /* Interior vertices have identical supports */ 3173 for (v = vStart; v < vEnd; ++v) { 3174 const PetscInt newp = vStartNew + (v - vStart); 3175 const PetscInt *support, *cone; 3176 PetscInt size, s; 3177 3178 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3179 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3180 for (s = 0; s < size; ++s) { 3181 PetscInt r = 0; 3182 3183 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3184 if (cone[1] == v) r = 1; 3185 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3186 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3187 } 3188 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3189 #if 1 3190 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3191 for (p = 0; p < size; ++p) { 3192 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); 3193 } 3194 #endif 3195 } 3196 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3197 for (e = eStart; e < eMax; ++e) { 3198 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3199 const PetscInt *cone, *support; 3200 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3201 3202 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3203 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3204 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3205 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3206 for (s = 0; s < size; ++s) { 3207 PetscInt r = 0; 3208 3209 if (support[s] < fMax) { 3210 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3211 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3212 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3213 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3214 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3215 faceSize += 2; 3216 } else { 3217 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3218 ++faceSize; 3219 } 3220 } 3221 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3222 for (s = 0; s < starSize*2; s += 2) { 3223 const PetscInt *cone, *ornt; 3224 PetscInt e01, e23; 3225 3226 if ((star[s] >= cStart) && (star[s] < cMax)) { 3227 /* Check edge 0-1 */ 3228 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3229 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3230 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3231 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3232 /* Check edge 2-3 */ 3233 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3234 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3235 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3236 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3237 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3238 } 3239 } 3240 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3241 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3242 #if 1 3243 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3244 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3245 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); 3246 } 3247 #endif 3248 } 3249 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3250 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3251 break; 3252 case 6: 3253 /* Hex 3D */ 3254 /* 3255 Bottom (viewed from top) Top 3256 1---------2---------2 7---------2---------6 3257 | | | | | | 3258 | B 2 C | | H 2 G | 3259 | | | | | | 3260 3----3----0----1----1 3----3----0----1----1 3261 | | | | | | 3262 | A 0 D | | E 0 F | 3263 | | | | | | 3264 0---------0---------3 4---------0---------5 3265 */ 3266 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3267 for (c = cStart; c < cEnd; ++c) { 3268 const PetscInt newp = (c - cStart)*8; 3269 const PetscInt *cone, *ornt; 3270 PetscInt coneNew[6], orntNew[6]; 3271 3272 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3273 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3274 /* A hex */ 3275 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3276 orntNew[0] = ornt[0]; 3277 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3278 orntNew[1] = 0; 3279 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3280 orntNew[2] = ornt[2]; 3281 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3282 orntNew[3] = 0; 3283 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3284 orntNew[4] = 0; 3285 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3286 orntNew[5] = ornt[5]; 3287 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3288 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3289 #if 1 3290 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); 3291 for (p = 0; p < 6; ++p) { 3292 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); 3293 } 3294 #endif 3295 /* B hex */ 3296 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3297 orntNew[0] = ornt[0]; 3298 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3299 orntNew[1] = 0; 3300 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3301 orntNew[2] = -1; 3302 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3303 orntNew[3] = ornt[3]; 3304 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3305 orntNew[4] = 0; 3306 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3307 orntNew[5] = ornt[5]; 3308 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3309 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3310 #if 1 3311 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); 3312 for (p = 0; p < 6; ++p) { 3313 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); 3314 } 3315 #endif 3316 /* C hex */ 3317 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3318 orntNew[0] = ornt[0]; 3319 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3320 orntNew[1] = 0; 3321 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3322 orntNew[2] = -1; 3323 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3324 orntNew[3] = ornt[3]; 3325 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3326 orntNew[4] = ornt[4]; 3327 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3328 orntNew[5] = -4; 3329 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3330 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3331 #if 1 3332 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); 3333 for (p = 0; p < 6; ++p) { 3334 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); 3335 } 3336 #endif 3337 /* D hex */ 3338 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3339 orntNew[0] = ornt[0]; 3340 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3341 orntNew[1] = 0; 3342 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3343 orntNew[2] = ornt[2]; 3344 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3345 orntNew[3] = 0; 3346 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3347 orntNew[4] = ornt[4]; 3348 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3349 orntNew[5] = -4; 3350 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3351 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3352 #if 1 3353 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); 3354 for (p = 0; p < 6; ++p) { 3355 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); 3356 } 3357 #endif 3358 /* E hex */ 3359 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3360 orntNew[0] = -4; 3361 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3362 orntNew[1] = ornt[1]; 3363 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3364 orntNew[2] = ornt[2]; 3365 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3366 orntNew[3] = 0; 3367 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3368 orntNew[4] = -1; 3369 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3370 orntNew[5] = ornt[5]; 3371 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3372 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3373 #if 1 3374 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); 3375 for (p = 0; p < 6; ++p) { 3376 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); 3377 } 3378 #endif 3379 /* F hex */ 3380 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3381 orntNew[0] = -4; 3382 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3383 orntNew[1] = ornt[1]; 3384 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3385 orntNew[2] = ornt[2]; 3386 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3387 orntNew[3] = -1; 3388 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3389 orntNew[4] = ornt[4]; 3390 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3391 orntNew[5] = 1; 3392 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3393 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3394 #if 1 3395 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); 3396 for (p = 0; p < 6; ++p) { 3397 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); 3398 } 3399 #endif 3400 /* G hex */ 3401 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3402 orntNew[0] = -4; 3403 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3404 orntNew[1] = ornt[1]; 3405 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3406 orntNew[2] = 0; 3407 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3408 orntNew[3] = ornt[3]; 3409 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3410 orntNew[4] = ornt[4]; 3411 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3412 orntNew[5] = -3; 3413 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3414 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3415 #if 1 3416 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); 3417 for (p = 0; p < 6; ++p) { 3418 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); 3419 } 3420 #endif 3421 /* H hex */ 3422 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3423 orntNew[0] = -4; 3424 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3425 orntNew[1] = ornt[1]; 3426 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3427 orntNew[2] = -1; 3428 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3429 orntNew[3] = ornt[3]; 3430 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3431 orntNew[4] = 3; 3432 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3433 orntNew[5] = ornt[5]; 3434 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3435 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3436 #if 1 3437 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); 3438 for (p = 0; p < 6; ++p) { 3439 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); 3440 } 3441 #endif 3442 } 3443 /* Split faces have 4 edges and the same cells as the parent */ 3444 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3445 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3446 for (f = fStart; f < fEnd; ++f) { 3447 for (r = 0; r < 4; ++r) { 3448 /* TODO: This can come from GetFaces_Internal() */ 3449 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}; 3450 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3451 const PetscInt *cone, *ornt, *support; 3452 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3453 3454 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3455 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3456 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3457 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3458 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3459 orntNew[(r+0)%4] = ornt[r]; 3460 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3461 orntNew[(r+1)%4] = 0; 3462 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3463 orntNew[(r+2)%4] = -2; 3464 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3465 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3466 #if 1 3467 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3468 for (p = 0; p < 4; ++p) { 3469 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); 3470 } 3471 #endif 3472 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3473 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3474 for (s = 0; s < supportSize; ++s) { 3475 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3476 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3477 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3478 for (c = 0; c < coneSize; ++c) { 3479 if (cone[c] == f) break; 3480 } 3481 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 3482 } 3483 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3484 #if 1 3485 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3486 for (p = 0; p < supportSize; ++p) { 3487 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); 3488 } 3489 #endif 3490 } 3491 } 3492 /* Interior faces have 4 edges and 2 cells */ 3493 for (c = cStart; c < cEnd; ++c) { 3494 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}; 3495 const PetscInt *cone, *ornt; 3496 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3497 3498 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3499 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3500 /* A-D face */ 3501 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3502 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3503 orntNew[0] = 0; 3504 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3505 orntNew[1] = 0; 3506 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3507 orntNew[2] = -2; 3508 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3509 orntNew[3] = -2; 3510 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3511 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3512 #if 1 3513 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3514 for (p = 0; p < 4; ++p) { 3515 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); 3516 } 3517 #endif 3518 /* C-D face */ 3519 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3520 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3521 orntNew[0] = 0; 3522 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3523 orntNew[1] = 0; 3524 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3525 orntNew[2] = -2; 3526 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3527 orntNew[3] = -2; 3528 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3529 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3530 #if 1 3531 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3532 for (p = 0; p < 4; ++p) { 3533 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); 3534 } 3535 #endif 3536 /* B-C face */ 3537 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3538 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3539 orntNew[0] = -2; 3540 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3541 orntNew[1] = 0; 3542 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3543 orntNew[2] = 0; 3544 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3545 orntNew[3] = -2; 3546 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3547 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3548 #if 1 3549 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3550 for (p = 0; p < 4; ++p) { 3551 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); 3552 } 3553 #endif 3554 /* A-B face */ 3555 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 3556 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 3557 orntNew[0] = -2; 3558 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 3559 orntNew[1] = 0; 3560 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3561 orntNew[2] = 0; 3562 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3563 orntNew[3] = -2; 3564 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3565 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3566 #if 1 3567 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3568 for (p = 0; p < 4; ++p) { 3569 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); 3570 } 3571 #endif 3572 /* E-F face */ 3573 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 3574 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3575 orntNew[0] = -2; 3576 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 3577 orntNew[1] = -2; 3578 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 3579 orntNew[2] = 0; 3580 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3581 orntNew[3] = 0; 3582 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3583 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3584 #if 1 3585 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3586 for (p = 0; p < 4; ++p) { 3587 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); 3588 } 3589 #endif 3590 /* F-G face */ 3591 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 3592 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3593 orntNew[0] = -2; 3594 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 3595 orntNew[1] = -2; 3596 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 3597 orntNew[2] = 0; 3598 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3599 orntNew[3] = 0; 3600 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3601 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3602 #if 1 3603 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3604 for (p = 0; p < 4; ++p) { 3605 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); 3606 } 3607 #endif 3608 /* G-H face */ 3609 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 3610 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 3611 orntNew[0] = -2; 3612 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 3613 orntNew[1] = 0; 3614 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3615 orntNew[2] = 0; 3616 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3617 orntNew[3] = -2; 3618 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3619 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3620 #if 1 3621 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3622 for (p = 0; p < 4; ++p) { 3623 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); 3624 } 3625 #endif 3626 /* E-H face */ 3627 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 3628 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3629 orntNew[0] = -2; 3630 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 3631 orntNew[1] = -2; 3632 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 3633 orntNew[2] = 0; 3634 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 3635 orntNew[3] = 0; 3636 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3637 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3638 #if 1 3639 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3640 for (p = 0; p < 4; ++p) { 3641 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); 3642 } 3643 #endif 3644 /* A-E face */ 3645 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 3646 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 3647 orntNew[0] = 0; 3648 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3649 orntNew[1] = 0; 3650 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3651 orntNew[2] = -2; 3652 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 3653 orntNew[3] = -2; 3654 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3655 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3656 #if 1 3657 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3658 for (p = 0; p < 4; ++p) { 3659 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); 3660 } 3661 #endif 3662 /* D-F face */ 3663 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 3664 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 3665 orntNew[0] = -2; 3666 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 3667 orntNew[1] = 0; 3668 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3669 orntNew[2] = 0; 3670 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3671 orntNew[3] = -2; 3672 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3673 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3674 #if 1 3675 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3676 for (p = 0; p < 4; ++p) { 3677 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); 3678 } 3679 #endif 3680 /* C-G face */ 3681 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 3682 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3683 orntNew[0] = -2; 3684 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 3685 orntNew[1] = -2; 3686 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 3687 orntNew[2] = 0; 3688 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3689 orntNew[3] = 0; 3690 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3691 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3692 #if 1 3693 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3694 for (p = 0; p < 4; ++p) { 3695 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); 3696 } 3697 #endif 3698 /* B-H face */ 3699 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 3700 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 3701 orntNew[0] = 0; 3702 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3703 orntNew[1] = -2; 3704 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 3705 orntNew[2] = -2; 3706 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 3707 orntNew[3] = 0; 3708 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3709 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3710 #if 1 3711 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3712 for (p = 0; p < 4; ++p) { 3713 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); 3714 } 3715 #endif 3716 for (r = 0; r < 12; ++r) { 3717 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 3718 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 3719 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 3720 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3721 #if 1 3722 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3723 for (p = 0; p < 2; ++p) { 3724 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); 3725 } 3726 #endif 3727 } 3728 } 3729 /* Split edges have 2 vertices and the same faces as the parent */ 3730 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3731 for (e = eStart; e < eEnd; ++e) { 3732 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3733 3734 for (r = 0; r < 2; ++r) { 3735 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3736 const PetscInt *cone, *ornt, *support; 3737 PetscInt coneNew[2], coneSize, c, supportSize, s; 3738 3739 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3740 coneNew[0] = vStartNew + (cone[0] - vStart); 3741 coneNew[1] = vStartNew + (cone[1] - vStart); 3742 coneNew[(r+1)%2] = newv; 3743 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3744 #if 1 3745 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3746 for (p = 0; p < 2; ++p) { 3747 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); 3748 } 3749 #endif 3750 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3751 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3752 for (s = 0; s < supportSize; ++s) { 3753 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3754 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3755 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3756 for (c = 0; c < coneSize; ++c) { 3757 if (cone[c] == e) break; 3758 } 3759 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3760 } 3761 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3762 #if 1 3763 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3764 for (p = 0; p < supportSize; ++p) { 3765 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); 3766 } 3767 #endif 3768 } 3769 } 3770 /* Face edges have 2 vertices and 2+cells faces */ 3771 for (f = fStart; f < fEnd; ++f) { 3772 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}; 3773 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3774 const PetscInt *cone, *coneCell, *orntCell, *support; 3775 PetscInt coneNew[2], coneSize, c, supportSize, s; 3776 3777 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3778 for (r = 0; r < 4; ++r) { 3779 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3780 3781 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 3782 coneNew[1] = newv; 3783 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3784 #if 1 3785 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3786 for (p = 0; p < 2; ++p) { 3787 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); 3788 } 3789 #endif 3790 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3791 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3792 supportRef[0] = fStartNew + (f - fStart)*4 + r; 3793 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 3794 for (s = 0; s < supportSize; ++s) { 3795 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3796 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3797 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3798 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 3799 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 3800 } 3801 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3802 #if 1 3803 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3804 for (p = 0; p < 2+supportSize; ++p) { 3805 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); 3806 } 3807 #endif 3808 } 3809 } 3810 /* Cell edges have 2 vertices and 4 faces */ 3811 for (c = cStart; c < cEnd; ++c) { 3812 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}; 3813 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3814 const PetscInt *cone; 3815 PetscInt coneNew[2], supportNew[4]; 3816 3817 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3818 for (r = 0; r < 6; ++r) { 3819 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3820 3821 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 3822 coneNew[1] = newv; 3823 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3824 #if 1 3825 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3826 for (p = 0; p < 2; ++p) { 3827 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); 3828 } 3829 #endif 3830 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 3831 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3832 #if 1 3833 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3834 for (p = 0; p < 4; ++p) { 3835 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); 3836 } 3837 #endif 3838 } 3839 } 3840 /* Old vertices have identical supports */ 3841 for (v = vStart; v < vEnd; ++v) { 3842 const PetscInt newp = vStartNew + (v - vStart); 3843 const PetscInt *support, *cone; 3844 PetscInt size, s; 3845 3846 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3847 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3848 for (s = 0; s < size; ++s) { 3849 PetscInt r = 0; 3850 3851 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3852 if (cone[1] == v) r = 1; 3853 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3854 } 3855 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3856 #if 1 3857 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3858 for (p = 0; p < size; ++p) { 3859 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); 3860 } 3861 #endif 3862 } 3863 /* Edge vertices have 2 + faces supports */ 3864 for (e = eStart; e < eEnd; ++e) { 3865 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3866 const PetscInt *cone, *support; 3867 PetscInt size, s; 3868 3869 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3870 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3871 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3872 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3873 for (s = 0; s < size; ++s) { 3874 PetscInt r; 3875 3876 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3877 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 3878 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 3879 } 3880 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3881 #if 1 3882 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3883 for (p = 0; p < 2+size; ++p) { 3884 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); 3885 } 3886 #endif 3887 } 3888 /* Face vertices have 4 + cells supports */ 3889 for (f = fStart; f < fEnd; ++f) { 3890 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 3891 const PetscInt *cone, *support; 3892 PetscInt size, s; 3893 3894 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3895 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3896 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3897 for (s = 0; s < size; ++s) { 3898 PetscInt r; 3899 3900 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3901 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 3902 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 3903 } 3904 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3905 #if 1 3906 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3907 for (p = 0; p < 4+size; ++p) { 3908 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); 3909 } 3910 #endif 3911 } 3912 /* Cell vertices have 6 supports */ 3913 for (c = cStart; c < cEnd; ++c) { 3914 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 3915 PetscInt supportNew[6]; 3916 3917 for (r = 0; r < 6; ++r) { 3918 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 3919 } 3920 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3921 } 3922 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3923 break; 3924 case 8: 3925 /* Hybrid Hex 3D */ 3926 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 3927 /* 3928 Bottom (viewed from top) Top 3929 1---------2---------2 7---------2---------6 3930 | | | | | | 3931 | B 2 C | | H 2 G | 3932 | | | | | | 3933 3----3----0----1----1 3----3----0----1----1 3934 | | | | | | 3935 | A 0 D | | E 0 F | 3936 | | | | | | 3937 0---------0---------3 4---------0---------5 3938 */ 3939 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3940 for (c = cStart; c < cMax; ++c) { 3941 const PetscInt newp = (c - cStart)*8; 3942 const PetscInt *cone, *ornt; 3943 PetscInt coneNew[6], orntNew[6]; 3944 3945 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3946 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3947 /* A hex */ 3948 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3949 orntNew[0] = ornt[0]; 3950 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3951 orntNew[1] = 0; 3952 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3953 orntNew[2] = ornt[2]; 3954 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3955 orntNew[3] = 0; 3956 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3957 orntNew[4] = 0; 3958 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3959 orntNew[5] = ornt[5]; 3960 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3961 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3962 #if 1 3963 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); 3964 for (p = 0; p < 6; ++p) { 3965 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); 3966 } 3967 #endif 3968 /* B hex */ 3969 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3970 orntNew[0] = ornt[0]; 3971 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3972 orntNew[1] = 0; 3973 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3974 orntNew[2] = -1; 3975 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3976 orntNew[3] = ornt[3]; 3977 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3978 orntNew[4] = 0; 3979 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3980 orntNew[5] = ornt[5]; 3981 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3982 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3983 #if 1 3984 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); 3985 for (p = 0; p < 6; ++p) { 3986 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); 3987 } 3988 #endif 3989 /* C hex */ 3990 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3991 orntNew[0] = ornt[0]; 3992 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3993 orntNew[1] = 0; 3994 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3995 orntNew[2] = -1; 3996 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3997 orntNew[3] = ornt[3]; 3998 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3999 orntNew[4] = ornt[4]; 4000 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4001 orntNew[5] = -4; 4002 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4003 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4004 #if 1 4005 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); 4006 for (p = 0; p < 6; ++p) { 4007 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); 4008 } 4009 #endif 4010 /* D hex */ 4011 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4012 orntNew[0] = ornt[0]; 4013 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4014 orntNew[1] = 0; 4015 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4016 orntNew[2] = ornt[2]; 4017 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4018 orntNew[3] = 0; 4019 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4020 orntNew[4] = ornt[4]; 4021 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4022 orntNew[5] = -4; 4023 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4024 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4025 #if 1 4026 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); 4027 for (p = 0; p < 6; ++p) { 4028 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); 4029 } 4030 #endif 4031 /* E hex */ 4032 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4033 orntNew[0] = -4; 4034 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4035 orntNew[1] = ornt[1]; 4036 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4037 orntNew[2] = ornt[2]; 4038 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4039 orntNew[3] = 0; 4040 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4041 orntNew[4] = -1; 4042 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4043 orntNew[5] = ornt[5]; 4044 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4045 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4046 #if 1 4047 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); 4048 for (p = 0; p < 6; ++p) { 4049 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); 4050 } 4051 #endif 4052 /* F hex */ 4053 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4054 orntNew[0] = -4; 4055 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4056 orntNew[1] = ornt[1]; 4057 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4058 orntNew[2] = ornt[2]; 4059 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4060 orntNew[3] = -1; 4061 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4062 orntNew[4] = ornt[4]; 4063 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4064 orntNew[5] = 1; 4065 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4066 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4067 #if 1 4068 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); 4069 for (p = 0; p < 6; ++p) { 4070 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); 4071 } 4072 #endif 4073 /* G hex */ 4074 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4075 orntNew[0] = -4; 4076 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4077 orntNew[1] = ornt[1]; 4078 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4079 orntNew[2] = 0; 4080 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4081 orntNew[3] = ornt[3]; 4082 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4083 orntNew[4] = ornt[4]; 4084 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4085 orntNew[5] = -3; 4086 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4087 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4088 #if 1 4089 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); 4090 for (p = 0; p < 6; ++p) { 4091 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); 4092 } 4093 #endif 4094 /* H hex */ 4095 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4096 orntNew[0] = -4; 4097 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4098 orntNew[1] = ornt[1]; 4099 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4100 orntNew[2] = -1; 4101 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4102 orntNew[3] = ornt[3]; 4103 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4104 orntNew[4] = 3; 4105 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4106 orntNew[5] = ornt[5]; 4107 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4108 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4109 #if 1 4110 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); 4111 for (p = 0; p < 6; ++p) { 4112 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); 4113 } 4114 #endif 4115 } 4116 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4117 /* 4118 3---------2---------2 4119 | | | 4120 | D 2 C | 4121 | | | 4122 3----3----0----1----1 4123 | | | 4124 | A 0 B | 4125 | | | 4126 0---------0---------1 4127 */ 4128 for (c = cMax; c < cEnd; ++c) { 4129 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4130 const PetscInt *cone, *ornt, *fornt; 4131 PetscInt coneNew[6], orntNew[6]; 4132 4133 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4134 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4135 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4136 for (r = 0; r < 4; ++r) { 4137 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4138 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4139 PetscInt edgeB = (edgeA+3)%4; 4140 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]); 4141 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4142 orntNew[0] = ornt[0]; 4143 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4144 orntNew[1] = ornt[0]; 4145 coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0); 4146 orntNew[(r+0)%4+2] = ornt[edgeA]; 4147 coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4148 orntNew[(r+1)%4+2] = 0; 4149 coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4150 orntNew[(r+2)%4+2] = -2; 4151 coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1); 4152 orntNew[(r+3)%4+2] = ornt[edgeB]; 4153 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4154 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4155 #if 1 4156 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); 4157 for (p = 0; p < 2; ++p) { 4158 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); 4159 } 4160 for (p = 2; p < 6; ++p) { 4161 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); 4162 } 4163 #endif 4164 } 4165 } 4166 /* Interior split faces have 4 edges and the same cells as the parent */ 4167 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4168 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 4169 for (f = fStart; f < fMax; ++f) { 4170 for (r = 0; r < 4; ++r) { 4171 /* TODO: This can come from GetFaces_Internal() */ 4172 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}; 4173 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4174 const PetscInt *cone, *ornt, *support; 4175 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4176 4177 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4178 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4179 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4180 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4181 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4182 orntNew[(r+0)%4] = ornt[r]; 4183 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4184 orntNew[(r+1)%4] = 0; 4185 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4186 orntNew[(r+2)%4] = -2; 4187 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4188 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4189 #if 1 4190 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4191 for (p = 0; p < 4; ++p) { 4192 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); 4193 } 4194 #endif 4195 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4196 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4197 for (s = 0; s < supportSize; ++s) { 4198 PetscInt subf; 4199 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4200 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4201 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4202 for (c = 0; c < coneSize; ++c) { 4203 if (cone[c] == f) break; 4204 } 4205 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4206 if (support[s] < cMax) { 4207 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4208 } else { 4209 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4210 } 4211 } 4212 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4213 #if 1 4214 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4215 for (p = 0; p < supportSize; ++p) { 4216 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); 4217 } 4218 #endif 4219 } 4220 } 4221 /* Interior faces have 4 edges and 2 cells */ 4222 for (c = cStart; c < cMax; ++c) { 4223 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}; 4224 const PetscInt *cone, *ornt; 4225 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4226 4227 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4228 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4229 /* A-D face */ 4230 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4231 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4232 orntNew[0] = 0; 4233 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4234 orntNew[1] = 0; 4235 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4236 orntNew[2] = -2; 4237 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4238 orntNew[3] = -2; 4239 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4240 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4241 #if 1 4242 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4243 for (p = 0; p < 4; ++p) { 4244 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); 4245 } 4246 #endif 4247 /* C-D face */ 4248 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4249 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4250 orntNew[0] = 0; 4251 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4252 orntNew[1] = 0; 4253 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4254 orntNew[2] = -2; 4255 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4256 orntNew[3] = -2; 4257 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4258 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4259 #if 1 4260 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4261 for (p = 0; p < 4; ++p) { 4262 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); 4263 } 4264 #endif 4265 /* B-C face */ 4266 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4267 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4268 orntNew[0] = -2; 4269 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4270 orntNew[1] = 0; 4271 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4272 orntNew[2] = 0; 4273 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4274 orntNew[3] = -2; 4275 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4276 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4277 #if 1 4278 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4279 for (p = 0; p < 4; ++p) { 4280 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); 4281 } 4282 #endif 4283 /* A-B face */ 4284 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4285 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4286 orntNew[0] = -2; 4287 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4288 orntNew[1] = 0; 4289 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4290 orntNew[2] = 0; 4291 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4292 orntNew[3] = -2; 4293 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4294 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4295 #if 1 4296 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4297 for (p = 0; p < 4; ++p) { 4298 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); 4299 } 4300 #endif 4301 /* E-F face */ 4302 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4303 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4304 orntNew[0] = -2; 4305 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4306 orntNew[1] = -2; 4307 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4308 orntNew[2] = 0; 4309 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4310 orntNew[3] = 0; 4311 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4312 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4313 #if 1 4314 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4315 for (p = 0; p < 4; ++p) { 4316 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); 4317 } 4318 #endif 4319 /* F-G face */ 4320 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4321 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4322 orntNew[0] = -2; 4323 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4324 orntNew[1] = -2; 4325 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4326 orntNew[2] = 0; 4327 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4328 orntNew[3] = 0; 4329 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4330 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4331 #if 1 4332 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4333 for (p = 0; p < 4; ++p) { 4334 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); 4335 } 4336 #endif 4337 /* G-H face */ 4338 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4339 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4340 orntNew[0] = -2; 4341 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4342 orntNew[1] = 0; 4343 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4344 orntNew[2] = 0; 4345 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4346 orntNew[3] = -2; 4347 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4348 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4349 #if 1 4350 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4351 for (p = 0; p < 4; ++p) { 4352 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); 4353 } 4354 #endif 4355 /* E-H face */ 4356 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4357 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4358 orntNew[0] = -2; 4359 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4360 orntNew[1] = -2; 4361 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4362 orntNew[2] = 0; 4363 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4364 orntNew[3] = 0; 4365 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4366 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4367 #if 1 4368 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4369 for (p = 0; p < 4; ++p) { 4370 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); 4371 } 4372 #endif 4373 /* A-E face */ 4374 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4375 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4376 orntNew[0] = 0; 4377 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4378 orntNew[1] = 0; 4379 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4380 orntNew[2] = -2; 4381 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4382 orntNew[3] = -2; 4383 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4384 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4385 #if 1 4386 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4387 for (p = 0; p < 4; ++p) { 4388 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); 4389 } 4390 #endif 4391 /* D-F face */ 4392 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4393 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4394 orntNew[0] = -2; 4395 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4396 orntNew[1] = 0; 4397 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4398 orntNew[2] = 0; 4399 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4400 orntNew[3] = -2; 4401 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4402 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4403 #if 1 4404 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4405 for (p = 0; p < 4; ++p) { 4406 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); 4407 } 4408 #endif 4409 /* C-G face */ 4410 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4411 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4412 orntNew[0] = -2; 4413 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4414 orntNew[1] = -2; 4415 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4416 orntNew[2] = 0; 4417 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4418 orntNew[3] = 0; 4419 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4420 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4421 #if 1 4422 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4423 for (p = 0; p < 4; ++p) { 4424 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); 4425 } 4426 #endif 4427 /* B-H face */ 4428 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 4429 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4430 orntNew[0] = 0; 4431 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4432 orntNew[1] = -2; 4433 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4434 orntNew[2] = -2; 4435 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4436 orntNew[3] = 0; 4437 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4438 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4439 #if 1 4440 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4441 for (p = 0; p < 4; ++p) { 4442 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); 4443 } 4444 #endif 4445 for (r = 0; r < 12; ++r) { 4446 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 4447 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4448 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4449 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4450 #if 1 4451 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4452 for (p = 0; p < 2; ++p) { 4453 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); 4454 } 4455 #endif 4456 } 4457 } 4458 /* Hybrid split faces have 4 edges and same cells */ 4459 for (f = fMax; f < fEnd; ++f) { 4460 const PetscInt *cone, *ornt, *support; 4461 PetscInt coneNew[4], orntNew[4]; 4462 PetscInt supportNew[2], size, s, c; 4463 4464 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4465 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4466 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4467 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4468 for (r = 0; r < 2; ++r) { 4469 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 4470 4471 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4472 orntNew[0] = ornt[0]; 4473 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4474 orntNew[1] = ornt[1]; 4475 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 4476 orntNew[2+r] = 0; 4477 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4478 orntNew[3-r] = 0; 4479 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4480 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4481 #if 1 4482 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4483 for (p = 0; p < 2; ++p) { 4484 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); 4485 } 4486 for (p = 2; p < 4; ++p) { 4487 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); 4488 } 4489 #endif 4490 for (s = 0; s < size; ++s) { 4491 const PetscInt *coneCell, *orntCell, *fornt; 4492 4493 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4494 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4495 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 4496 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 4497 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4498 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%4; 4499 } 4500 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4501 #if 1 4502 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4503 for (p = 0; p < size; ++p) { 4504 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); 4505 } 4506 #endif 4507 } 4508 } 4509 /* Hybrid cell faces have 4 edges and 2 cells */ 4510 for (c = cMax; c < cEnd; ++c) { 4511 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 4512 const PetscInt *cone, *ornt; 4513 PetscInt coneNew[4], orntNew[4]; 4514 PetscInt supportNew[2]; 4515 4516 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4517 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4518 for (r = 0; r < 4; ++r) { 4519 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 4520 orntNew[0] = 0; 4521 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 4522 orntNew[1] = 0; 4523 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 4524 orntNew[2] = 0; 4525 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4526 orntNew[3] = 0; 4527 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4528 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4529 #if 1 4530 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); 4531 for (p = 0; p < 2; ++p) { 4532 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); 4533 } 4534 for (p = 2; p < 4; ++p) { 4535 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); 4536 } 4537 #endif 4538 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 4539 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 4540 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4541 #if 1 4542 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); 4543 for (p = 0; p < 2; ++p) { 4544 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); 4545 } 4546 #endif 4547 } 4548 } 4549 /* Interior split edges have 2 vertices and the same faces as the parent */ 4550 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4551 for (e = eStart; e < eMax; ++e) { 4552 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4553 4554 for (r = 0; r < 2; ++r) { 4555 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4556 const PetscInt *cone, *ornt, *support; 4557 PetscInt coneNew[2], coneSize, c, supportSize, s; 4558 4559 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4560 coneNew[0] = vStartNew + (cone[0] - vStart); 4561 coneNew[1] = vStartNew + (cone[1] - vStart); 4562 coneNew[(r+1)%2] = newv; 4563 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4564 #if 1 4565 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4566 for (p = 0; p < 2; ++p) { 4567 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); 4568 } 4569 #endif 4570 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4571 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4572 for (s = 0; s < supportSize; ++s) { 4573 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4574 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4575 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4576 for (c = 0; c < coneSize; ++c) { 4577 if (cone[c] == e) break; 4578 } 4579 if (support[s] < fMax) { 4580 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 4581 } else { 4582 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4583 } 4584 } 4585 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4586 #if 1 4587 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4588 for (p = 0; p < supportSize; ++p) { 4589 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); 4590 } 4591 #endif 4592 } 4593 } 4594 /* Interior face edges have 2 vertices and 2+cells faces */ 4595 for (f = fStart; f < fMax; ++f) { 4596 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}; 4597 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 4598 const PetscInt *cone, *coneCell, *orntCell, *support; 4599 PetscInt coneNew[2], coneSize, c, supportSize, s; 4600 4601 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4602 for (r = 0; r < 4; ++r) { 4603 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4604 4605 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4606 coneNew[1] = newv; 4607 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4608 #if 1 4609 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4610 for (p = 0; p < 2; ++p) { 4611 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); 4612 } 4613 #endif 4614 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4615 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4616 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4617 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4618 for (s = 0; s < supportSize; ++s) { 4619 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4620 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4621 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4622 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4623 if (support[s] < cMax) { 4624 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4625 } else { 4626 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r); 4627 } 4628 } 4629 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4630 #if 1 4631 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4632 for (p = 0; p < 2+supportSize; ++p) { 4633 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); 4634 } 4635 #endif 4636 } 4637 } 4638 /* Interior cell edges have 2 vertices and 4 faces */ 4639 for (c = cStart; c < cMax; ++c) { 4640 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}; 4641 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 4642 const PetscInt *cone; 4643 PetscInt coneNew[2], supportNew[4]; 4644 4645 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4646 for (r = 0; r < 6; ++r) { 4647 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 4648 4649 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 4650 coneNew[1] = newv; 4651 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4652 #if 1 4653 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4654 for (p = 0; p < 2; ++p) { 4655 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); 4656 } 4657 #endif 4658 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4659 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4660 #if 1 4661 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4662 for (p = 0; p < 4; ++p) { 4663 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); 4664 } 4665 #endif 4666 } 4667 } 4668 /* Hybrid edges have two vertices and the same faces */ 4669 for (e = eMax; e < eEnd; ++e) { 4670 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 4671 const PetscInt *cone, *support, *fcone; 4672 PetscInt coneNew[2], size, fsize, s; 4673 4674 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4675 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4676 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4677 coneNew[0] = vStartNew + (cone[0] - vStart); 4678 coneNew[1] = vStartNew + (cone[1] - vStart); 4679 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4680 #if 1 4681 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4682 for (p = 0; p < 2; ++p) { 4683 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); 4684 } 4685 #endif 4686 for (s = 0; s < size; ++s) { 4687 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4688 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4689 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4690 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 4691 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 4692 } 4693 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4694 #if 1 4695 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4696 for (p = 0; p < size; ++p) { 4697 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); 4698 } 4699 #endif 4700 } 4701 /* Hybrid face edges have 2 vertices and 2+cells faces */ 4702 for (f = fMax; f < fEnd; ++f) { 4703 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4704 const PetscInt *cone, *support, *ccone, *cornt; 4705 PetscInt coneNew[2], size, csize, s; 4706 4707 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4708 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4709 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4710 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4711 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4712 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4713 #if 1 4714 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4715 for (p = 0; p < 2; ++p) { 4716 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); 4717 } 4718 #endif 4719 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 4720 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 4721 for (s = 0; s < size; ++s) { 4722 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4723 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4724 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4725 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4726 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]); 4727 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadSubfaceInverse_Static(cornt[0], c-2); 4728 } 4729 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4730 #if 1 4731 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4732 for (p = 0; p < 2+size; ++p) { 4733 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); 4734 } 4735 #endif 4736 } 4737 /* Hybrid cell edges have 2 vertices and 4 faces */ 4738 for (c = cMax; c < cEnd; ++c) { 4739 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4740 const PetscInt *cone, *support; 4741 PetscInt coneNew[2], size; 4742 4743 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4744 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 4745 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 4746 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 4747 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 4748 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4749 #if 1 4750 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4751 for (p = 0; p < 2; ++p) { 4752 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); 4753 } 4754 #endif 4755 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 4756 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 4757 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 4758 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 4759 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4760 #if 1 4761 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4762 for (p = 0; p < 4; ++p) { 4763 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); 4764 } 4765 #endif 4766 } 4767 /* Interior vertices have identical supports */ 4768 for (v = vStart; v < vEnd; ++v) { 4769 const PetscInt newp = vStartNew + (v - vStart); 4770 const PetscInt *support, *cone; 4771 PetscInt size, s; 4772 4773 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4774 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4775 for (s = 0; s < size; ++s) { 4776 PetscInt r = 0; 4777 4778 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4779 if (cone[1] == v) r = 1; 4780 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4781 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 4782 } 4783 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4784 #if 1 4785 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4786 for (p = 0; p < size; ++p) { 4787 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); 4788 } 4789 #endif 4790 } 4791 /* Interior edge vertices have 2 + faces supports */ 4792 for (e = eStart; e < eMax; ++e) { 4793 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4794 const PetscInt *cone, *support; 4795 PetscInt size, s; 4796 4797 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4798 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4799 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4800 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4801 for (s = 0; s < size; ++s) { 4802 PetscInt r; 4803 4804 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4805 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4806 if (support[s] < fMax) { 4807 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 4808 } else { 4809 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 4810 } 4811 } 4812 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4813 #if 1 4814 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4815 for (p = 0; p < 2+size; ++p) { 4816 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); 4817 } 4818 #endif 4819 } 4820 /* Interior face vertices have 4 + cells supports */ 4821 for (f = fStart; f < fMax; ++f) { 4822 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 4823 const PetscInt *cone, *support; 4824 PetscInt size, s; 4825 4826 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4827 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4828 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4829 for (s = 0; s < size; ++s) { 4830 PetscInt r; 4831 4832 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4833 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4834 if (support[s] < cMax) { 4835 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 4836 } else { 4837 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 4838 } 4839 } 4840 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4841 #if 1 4842 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4843 for (p = 0; p < 4+size; ++p) { 4844 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); 4845 } 4846 #endif 4847 } 4848 /* Cell vertices have 6 supports */ 4849 for (c = cStart; c < cMax; ++c) { 4850 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 4851 PetscInt supportNew[6]; 4852 4853 for (r = 0; r < 6; ++r) { 4854 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 4855 } 4856 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4857 } 4858 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4859 break; 4860 default: 4861 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4862 } 4863 PetscFunctionReturn(0); 4864 } 4865 4866 #undef __FUNCT__ 4867 #define __FUNCT__ "CellRefinerSetCoordinates" 4868 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 4869 { 4870 PetscSection coordSection, coordSectionNew; 4871 Vec coordinates, coordinatesNew; 4872 PetscScalar *coords, *coordsNew; 4873 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 4874 PetscInt dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 4875 PetscErrorCode ierr; 4876 4877 PetscFunctionBegin; 4878 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 4879 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 4880 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 4881 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 4882 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 4883 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 4884 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 4885 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 4886 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 4887 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 4888 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 4889 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 4890 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 4891 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 4892 if (cMax < 0) cMax = cEnd; 4893 if (fMax < 0) fMax = fEnd; 4894 if (eMax < 0) eMax = eEnd; 4895 /* All vertices have the dim coordinates */ 4896 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 4897 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 4898 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 4899 } 4900 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 4901 ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 4902 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 4903 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 4904 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 4905 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 4906 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 4907 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 4908 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 4909 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 4910 switch (refiner) { 4911 case 0: break; 4912 case 6: /* Hex 3D */ 4913 case 8: /* Hybrid Hex 3D */ 4914 /* Face vertices have the average of corner coordinates */ 4915 for (f = fStart; f < fMax; ++f) { 4916 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 4917 PetscInt *cone = NULL; 4918 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 4919 4920 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 4921 for (p = 0; p < closureSize*2; p += 2) { 4922 const PetscInt point = cone[p]; 4923 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 4924 } 4925 for (v = 0; v < coneSize; ++v) { 4926 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 4927 } 4928 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 4929 for (d = 0; d < dim; ++d) { 4930 coordsNew[offnew+d] = 0.0; 4931 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 4932 coordsNew[offnew+d] /= coneSize; 4933 } 4934 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 4935 } 4936 case 2: /* Hex 2D */ 4937 /* Cell vertices have the average of corner coordinates */ 4938 for (c = cStart; c < cMax; ++c) { 4939 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 4940 PetscInt *cone = NULL; 4941 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 4942 4943 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 4944 for (p = 0; p < closureSize*2; p += 2) { 4945 const PetscInt point = cone[p]; 4946 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 4947 } 4948 for (v = 0; v < coneSize; ++v) { 4949 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 4950 } 4951 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 4952 for (d = 0; d < dim; ++d) { 4953 coordsNew[offnew+d] = 0.0; 4954 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 4955 coordsNew[offnew+d] /= coneSize; 4956 } 4957 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 4958 } 4959 case 1: /* Simplicial 2D */ 4960 case 3: /* Hybrid Simplicial 2D */ 4961 case 5: /* Simplicial 3D */ 4962 case 7: /* Hybrid Simplicial 3D */ 4963 /* Edge vertices have the average of endpoint coordinates */ 4964 for (e = eStart; e < eMax; ++e) { 4965 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4966 const PetscInt *cone; 4967 PetscInt coneSize, offA, offB, offnew, d; 4968 4969 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 4970 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 4971 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4972 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 4973 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 4974 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 4975 for (d = 0; d < dim; ++d) { 4976 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 4977 } 4978 } 4979 /* Old vertices have the same coordinates */ 4980 for (v = vStart; v < vEnd; ++v) { 4981 const PetscInt newv = vStartNew + (v - vStart); 4982 PetscInt off, offnew, d; 4983 4984 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 4985 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 4986 for (d = 0; d < dim; ++d) { 4987 coordsNew[offnew+d] = coords[off+d]; 4988 } 4989 } 4990 break; 4991 default: 4992 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 4993 } 4994 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 4995 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 4996 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 4997 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 4998 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 4999 PetscFunctionReturn(0); 5000 } 5001 5002 #undef __FUNCT__ 5003 #define __FUNCT__ "DMPlexCreateProcessSF" 5004 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5005 { 5006 PetscInt numRoots, numLeaves, l; 5007 const PetscInt *localPoints; 5008 const PetscSFNode *remotePoints; 5009 PetscInt *localPointsNew; 5010 PetscSFNode *remotePointsNew; 5011 PetscInt *ranks, *ranksNew; 5012 PetscErrorCode ierr; 5013 5014 PetscFunctionBegin; 5015 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5016 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5017 for (l = 0; l < numLeaves; ++l) { 5018 ranks[l] = remotePoints[l].rank; 5019 } 5020 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5021 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5022 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5023 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5024 for (l = 0; l < numLeaves; ++l) { 5025 ranksNew[l] = ranks[l]; 5026 localPointsNew[l] = l; 5027 remotePointsNew[l].index = 0; 5028 remotePointsNew[l].rank = ranksNew[l]; 5029 } 5030 ierr = PetscFree(ranks);CHKERRQ(ierr); 5031 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 5032 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5033 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5034 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5035 PetscFunctionReturn(0); 5036 } 5037 5038 #undef __FUNCT__ 5039 #define __FUNCT__ "CellRefinerCreateSF" 5040 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5041 { 5042 PetscSF sf, sfNew, sfProcess; 5043 IS processRanks; 5044 MPI_Datatype depthType; 5045 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5046 const PetscInt *localPoints, *neighbors; 5047 const PetscSFNode *remotePoints; 5048 PetscInt *localPointsNew; 5049 PetscSFNode *remotePointsNew; 5050 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5051 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5052 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5053 PetscErrorCode ierr; 5054 5055 PetscFunctionBegin; 5056 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5057 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5058 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5059 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5060 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5061 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5062 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5063 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5064 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5065 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5066 /* Caculate size of new SF */ 5067 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5068 if (numRoots < 0) PetscFunctionReturn(0); 5069 for (l = 0; l < numLeaves; ++l) { 5070 const PetscInt p = localPoints[l]; 5071 5072 switch (refiner) { 5073 case 1: 5074 /* Simplicial 2D */ 5075 if ((p >= vStart) && (p < vEnd)) { 5076 /* Old vertices stay the same */ 5077 ++numLeavesNew; 5078 } else if ((p >= fStart) && (p < fEnd)) { 5079 /* Old faces add new faces and vertex */ 5080 numLeavesNew += 2 + 1; 5081 } else if ((p >= cStart) && (p < cEnd)) { 5082 /* Old cells add new cells and interior faces */ 5083 numLeavesNew += 4 + 3; 5084 } 5085 break; 5086 case 2: 5087 /* Hex 2D */ 5088 if ((p >= vStart) && (p < vEnd)) { 5089 /* Old vertices stay the same */ 5090 ++numLeavesNew; 5091 } else if ((p >= fStart) && (p < fEnd)) { 5092 /* Old faces add new faces and vertex */ 5093 numLeavesNew += 2 + 1; 5094 } else if ((p >= cStart) && (p < cEnd)) { 5095 /* Old cells add new cells, interior faces, and vertex */ 5096 numLeavesNew += 4 + 4 + 1; 5097 } 5098 break; 5099 case 5: 5100 /* Simplicial 3D */ 5101 if ((p >= vStart) && (p < vEnd)) { 5102 /* Old vertices stay the same */ 5103 ++numLeavesNew; 5104 } else if ((p >= eStart) && (p < eEnd)) { 5105 /* Old edges add new edges and vertex */ 5106 numLeavesNew += 2 + 1; 5107 } else if ((p >= fStart) && (p < fEnd)) { 5108 /* Old faces add new faces and face edges */ 5109 numLeavesNew += 4 + 3; 5110 } else if ((p >= cStart) && (p < cEnd)) { 5111 /* Old cells add new cells and interior faces and edges */ 5112 numLeavesNew += 8 + 8 + 1; 5113 } 5114 break; 5115 case 7: 5116 /* Hybrid Simplicial 3D */ 5117 if ((p >= vStart) && (p < vEnd)) { 5118 /* Interior vertices stay the same */ 5119 ++numLeavesNew; 5120 } else if ((p >= eStart) && (p < eMax)) { 5121 /* Interior edges add new edges and vertex */ 5122 numLeavesNew += 2 + 1; 5123 } else if ((p >= eMax) && (p < eEnd)) { 5124 /* Hybrid edges stay the same */ 5125 ++numLeavesNew; 5126 } else if ((p >= fStart) && (p < fMax)) { 5127 /* Interior faces add new faces and edges */ 5128 numLeavesNew += 4 + 3; 5129 } else if ((p >= fMax) && (p < fEnd)) { 5130 /* Hybrid faces add new faces and edges */ 5131 numLeavesNew += 2 + 1; 5132 } else if ((p >= cStart) && (p < cMax)) { 5133 /* Interior cells add new cells, faces, and edges */ 5134 numLeavesNew += 8 + 8 + 1; 5135 } else if ((p >= cMax) && (p < cEnd)) { 5136 /* Hybrid cells add new cells and faces */ 5137 numLeavesNew += 4 + 3; 5138 } 5139 break; 5140 case 6: 5141 /* Hex 3D */ 5142 if ((p >= vStart) && (p < vEnd)) { 5143 /* Old vertices stay the same */ 5144 ++numLeavesNew; 5145 } else if ((p >= eStart) && (p < eEnd)) { 5146 /* Old edges add new edges, and vertex */ 5147 numLeavesNew += 2 + 1; 5148 } else if ((p >= fStart) && (p < fEnd)) { 5149 /* Old faces add new faces, edges, and vertex */ 5150 numLeavesNew += 4 + 4 + 1; 5151 } else if ((p >= cStart) && (p < cEnd)) { 5152 /* Old cells add new cells, faces, edges, and vertex */ 5153 numLeavesNew += 8 + 12 + 6 + 1; 5154 } 5155 break; 5156 case 8: 5157 /* Hybrid Hex 3D */ 5158 if ((p >= vStart) && (p < vEnd)) { 5159 /* Old vertices stay the same */ 5160 ++numLeavesNew; 5161 } else if ((p >= eStart) && (p < eMax)) { 5162 /* Interior edges add new edges, and vertex */ 5163 numLeavesNew += 2 + 1; 5164 } else if ((p >= eMax) && (p < eEnd)) { 5165 /* Hybrid edges stay the same */ 5166 ++numLeavesNew; 5167 } else if ((p >= fStart) && (p < fMax)) { 5168 /* Interior faces add new faces, edges, and vertex */ 5169 numLeavesNew += 4 + 4 + 1; 5170 } else if ((p >= fMax) && (p < fEnd)) { 5171 /* Hybrid faces add new faces and edges */ 5172 numLeavesNew += 2 + 1; 5173 } else if ((p >= cStart) && (p < cMax)) { 5174 /* Interior cells add new cells, faces, edges, and vertex */ 5175 numLeavesNew += 8 + 12 + 6 + 1; 5176 } else if ((p >= cStart) && (p < cEnd)) { 5177 /* Hybrid cells add new cells, faces, and edges */ 5178 numLeavesNew += 4 + 4 + 1; 5179 } 5180 break; 5181 default: 5182 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5183 } 5184 } 5185 /* Communicate depthSizes for each remote rank */ 5186 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5187 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5188 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5189 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5190 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5191 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5192 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5193 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5194 for (n = 0; n < numNeighbors; ++n) { 5195 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5196 } 5197 depthSizeOld[depth] = cMax; 5198 depthSizeOld[0] = vMax; 5199 depthSizeOld[depth-1] = fMax; 5200 depthSizeOld[1] = eMax; 5201 5202 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5203 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5204 5205 depthSizeOld[depth] = cEnd - cStart; 5206 depthSizeOld[0] = vEnd - vStart; 5207 depthSizeOld[depth-1] = fEnd - fStart; 5208 depthSizeOld[1] = eEnd - eStart; 5209 5210 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5211 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5212 for (n = 0; n < numNeighbors; ++n) { 5213 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5214 } 5215 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5216 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5217 /* Calculate new point SF */ 5218 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5219 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5220 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5221 for (l = 0, m = 0; l < numLeaves; ++l) { 5222 PetscInt p = localPoints[l]; 5223 PetscInt rp = remotePoints[l].index, n; 5224 PetscMPIInt rrank = remotePoints[l].rank; 5225 5226 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5227 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5228 switch (refiner) { 5229 case 1: 5230 /* Simplicial 2D */ 5231 if ((p >= vStart) && (p < vEnd)) { 5232 /* Old vertices stay the same */ 5233 localPointsNew[m] = vStartNew + (p - vStart); 5234 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5235 remotePointsNew[m].rank = rrank; 5236 ++m; 5237 } else if ((p >= fStart) && (p < fEnd)) { 5238 /* Old faces add new faces and vertex */ 5239 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5240 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5241 remotePointsNew[m].rank = rrank; 5242 ++m; 5243 for (r = 0; r < 2; ++r, ++m) { 5244 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5245 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5246 remotePointsNew[m].rank = rrank; 5247 } 5248 } else if ((p >= cStart) && (p < cEnd)) { 5249 /* Old cells add new cells and interior faces */ 5250 for (r = 0; r < 4; ++r, ++m) { 5251 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5252 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5253 remotePointsNew[m].rank = rrank; 5254 } 5255 for (r = 0; r < 3; ++r, ++m) { 5256 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5257 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 5258 remotePointsNew[m].rank = rrank; 5259 } 5260 } 5261 break; 5262 case 2: 5263 /* Hex 2D */ 5264 if ((p >= vStart) && (p < vEnd)) { 5265 /* Old vertices stay the same */ 5266 localPointsNew[m] = vStartNew + (p - vStart); 5267 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5268 remotePointsNew[m].rank = rrank; 5269 ++m; 5270 } else if ((p >= fStart) && (p < fEnd)) { 5271 /* Old faces add new faces and vertex */ 5272 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5273 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5274 remotePointsNew[m].rank = rrank; 5275 ++m; 5276 for (r = 0; r < 2; ++r, ++m) { 5277 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5278 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5279 remotePointsNew[m].rank = rrank; 5280 } 5281 } else if ((p >= cStart) && (p < cEnd)) { 5282 /* Old cells add new cells, interior faces, and vertex */ 5283 for (r = 0; r < 4; ++r, ++m) { 5284 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5285 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5286 remotePointsNew[m].rank = rrank; 5287 } 5288 for (r = 0; r < 4; ++r, ++m) { 5289 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 5290 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 5291 remotePointsNew[m].rank = rrank; 5292 } 5293 for (r = 0; r < 1; ++r, ++m) { 5294 localPointsNew[m] = vStartNew + (fEnd - fStart) + (p - cStart) + r; 5295 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 5296 remotePointsNew[m].rank = rrank; 5297 } 5298 } 5299 break; 5300 case 3: 5301 /* Hybrid simplicial 2D */ 5302 if ((p >= vStart) && (p < vEnd)) { 5303 /* Old vertices stay the same */ 5304 localPointsNew[m] = vStartNew + (p - vStart); 5305 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5306 remotePointsNew[m].rank = rrank; 5307 ++m; 5308 } else if ((p >= fStart) && (p < fMax)) { 5309 /* Old interior faces add new faces and vertex */ 5310 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5311 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5312 remotePointsNew[m].rank = rrank; 5313 ++m; 5314 for (r = 0; r < 2; ++r, ++m) { 5315 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5316 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5317 remotePointsNew[m].rank = rrank; 5318 } 5319 } else if ((p >= fMax) && (p < fEnd)) { 5320 /* Old hybrid faces stay the same */ 5321 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5322 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5323 remotePointsNew[m].rank = rrank; 5324 ++m; 5325 } else if ((p >= cStart) && (p < cMax)) { 5326 /* Old interior cells add new cells and interior faces */ 5327 for (r = 0; r < 4; ++r, ++m) { 5328 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5329 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5330 remotePointsNew[m].rank = rrank; 5331 } 5332 for (r = 0; r < 3; ++r, ++m) { 5333 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5334 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5335 remotePointsNew[m].rank = rrank; 5336 } 5337 } else if ((p >= cStart) && (p < cMax)) { 5338 /* Old hybrid cells add new cells and hybrid face */ 5339 for (r = 0; r < 2; ++r, ++m) { 5340 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5341 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5342 remotePointsNew[m].rank = rrank; 5343 } 5344 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5345 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]); 5346 remotePointsNew[m].rank = rrank; 5347 ++m; 5348 } 5349 break; 5350 case 5: 5351 /* Simplicial 3D */ 5352 if ((p >= vStart) && (p < vEnd)) { 5353 /* Old vertices stay the same */ 5354 localPointsNew[m] = vStartNew + (p - vStart); 5355 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5356 remotePointsNew[m].rank = rrank; 5357 ++m; 5358 } else if ((p >= eStart) && (p < eEnd)) { 5359 /* Old edges add new edges and vertex */ 5360 for (r = 0; r < 2; ++r, ++m) { 5361 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5362 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5363 remotePointsNew[m].rank = rrank; 5364 } 5365 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5366 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5367 remotePointsNew[m].rank = rrank; 5368 ++m; 5369 } else if ((p >= fStart) && (p < fEnd)) { 5370 /* Old faces add new faces and face edges */ 5371 for (r = 0; r < 4; ++r, ++m) { 5372 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5373 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5374 remotePointsNew[m].rank = rrank; 5375 } 5376 for (r = 0; r < 3; ++r, ++m) { 5377 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 5378 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 5379 remotePointsNew[m].rank = rrank; 5380 } 5381 } else if ((p >= cStart) && (p < cEnd)) { 5382 /* Old cells add new cells and interior faces and edges */ 5383 for (r = 0; r < 8; ++r, ++m) { 5384 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5385 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5386 remotePointsNew[m].rank = rrank; 5387 } 5388 for (r = 0; r < 8; ++r, ++m) { 5389 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 5390 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 5391 remotePointsNew[m].rank = rrank; 5392 } 5393 for (r = 0; r < 1; ++r, ++m) { 5394 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 5395 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 5396 remotePointsNew[m].rank = rrank; 5397 } 5398 } 5399 break; 5400 case 7: 5401 /* Hybrid Simplicial 3D */ 5402 if ((p >= vStart) && (p < vEnd)) { 5403 /* Interior vertices stay the same */ 5404 localPointsNew[m] = vStartNew + (p - vStart); 5405 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5406 remotePointsNew[m].rank = rrank; 5407 ++m; 5408 } else if ((p >= eStart) && (p < eMax)) { 5409 /* Interior edges add new edges and vertex */ 5410 for (r = 0; r < 2; ++r, ++m) { 5411 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5412 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5413 remotePointsNew[m].rank = rrank; 5414 } 5415 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5416 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5417 remotePointsNew[m].rank = rrank; 5418 ++m; 5419 } else if ((p >= eMax) && (p < eEnd)) { 5420 /* Hybrid edges stay the same */ 5421 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5422 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+1]); 5423 remotePointsNew[m].rank = rrank; 5424 ++m; 5425 } else if ((p >= fStart) && (p < fMax)) { 5426 /* Interior faces add new faces and edges */ 5427 for (r = 0; r < 4; ++r, ++m) { 5428 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5429 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5430 remotePointsNew[m].rank = rrank; 5431 } 5432 for (r = 0; r < 3; ++r, ++m) { 5433 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5434 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5435 remotePointsNew[m].rank = rrank; 5436 } 5437 } else if ((p >= fMax) && (p < fEnd)) { 5438 /* Hybrid faces add new faces and edges */ 5439 for (r = 0; r < 2; ++r, ++m) { 5440 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5441 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; 5442 remotePointsNew[m].rank = rrank; 5443 } 5444 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 5445 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5446 remotePointsNew[m].rank = rrank; 5447 ++m; 5448 } else if ((p >= cStart) && (p < cMax)) { 5449 /* Interior cells add new cells, faces, and edges */ 5450 for (r = 0; r < 8; ++r, ++m) { 5451 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5452 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5453 remotePointsNew[m].rank = rrank; 5454 } 5455 for (r = 0; r < 8; ++r, ++m) { 5456 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5457 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 5458 remotePointsNew[m].rank = rrank; 5459 } 5460 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 5461 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; 5462 remotePointsNew[m].rank = rrank; 5463 ++m; 5464 } else if ((p >= cMax) && (p < cEnd)) { 5465 /* Hybrid cells add new cells and faces */ 5466 for (r = 0; r < 4; ++r, ++m) { 5467 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5468 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5469 remotePointsNew[m].rank = rrank; 5470 } 5471 for (r = 0; r < 3; ++r, ++m) { 5472 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5473 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; 5474 remotePointsNew[m].rank = rrank; 5475 } 5476 } 5477 break; 5478 case 6: 5479 /* Hex 3D */ 5480 if ((p >= vStart) && (p < vEnd)) { 5481 /* Old vertices stay the same */ 5482 localPointsNew[m] = vStartNew + (p - vStart); 5483 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5484 remotePointsNew[m].rank = rrank; 5485 ++m; 5486 } else if ((p >= eStart) && (p < eEnd)) { 5487 /* Old edges add new edges and vertex */ 5488 for (r = 0; r < 2; ++r, ++m) { 5489 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5490 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5491 remotePointsNew[m].rank = rrank; 5492 } 5493 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5494 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5495 remotePointsNew[m].rank = rrank; 5496 ++m; 5497 } else if ((p >= fStart) && (p < fEnd)) { 5498 /* Old faces add new faces, edges, and vertex */ 5499 for (r = 0; r < 4; ++r, ++m) { 5500 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5501 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5502 remotePointsNew[m].rank = rrank; 5503 } 5504 for (r = 0; r < 4; ++r, ++m) { 5505 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 5506 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 5507 remotePointsNew[m].rank = rrank; 5508 } 5509 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 5510 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 5511 remotePointsNew[m].rank = rrank; 5512 ++m; 5513 } else if ((p >= cStart) && (p < cEnd)) { 5514 /* Old cells add new cells, faces, edges, and vertex */ 5515 for (r = 0; r < 8; ++r, ++m) { 5516 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5517 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5518 remotePointsNew[m].rank = rrank; 5519 } 5520 for (r = 0; r < 12; ++r, ++m) { 5521 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 5522 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 5523 remotePointsNew[m].rank = rrank; 5524 } 5525 for (r = 0; r < 6; ++r, ++m) { 5526 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 5527 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 5528 remotePointsNew[m].rank = rrank; 5529 } 5530 for (r = 0; r < 1; ++r, ++m) { 5531 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 5532 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 5533 remotePointsNew[m].rank = rrank; 5534 } 5535 } 5536 break; 5537 case 8: 5538 /* Hybrid Hex 3D */ 5539 if ((p >= vStart) && (p < vEnd)) { 5540 /* Interior vertices stay the same */ 5541 localPointsNew[m] = vStartNew + (p - vStart); 5542 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5543 remotePointsNew[m].rank = rrank; 5544 ++m; 5545 } else if ((p >= eStart) && (p < eMax)) { 5546 /* Interior edges add new edges and vertex */ 5547 for (r = 0; r < 2; ++r, ++m) { 5548 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5549 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5550 remotePointsNew[m].rank = rrank; 5551 } 5552 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5553 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5554 remotePointsNew[m].rank = rrank; 5555 ++m; 5556 } else if ((p >= eMax) && (p < eEnd)) { 5557 /* Hybrid edges stay the same */ 5558 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 5559 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]); 5560 remotePointsNew[m].rank = rrank; 5561 ++m; 5562 } else if ((p >= fStart) && (p < fMax)) { 5563 /* Interior faces add new faces, edges, and vertex */ 5564 for (r = 0; r < 4; ++r, ++m) { 5565 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5566 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5567 remotePointsNew[m].rank = rrank; 5568 } 5569 for (r = 0; r < 4; ++r, ++m) { 5570 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 5571 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 5572 remotePointsNew[m].rank = rrank; 5573 } 5574 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 5575 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 5576 remotePointsNew[m].rank = rrank; 5577 ++m; 5578 } else if ((p >= fMax) && (p < fEnd)) { 5579 /* Hybrid faces add new faces and edges */ 5580 for (r = 0; r < 2; ++r, ++m) { 5581 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5582 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; 5583 remotePointsNew[m].rank = rrank; 5584 } 5585 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax); 5586 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]); 5587 remotePointsNew[m].rank = rrank; 5588 ++m; 5589 } else if ((p >= cStart) && (p < cMax)) { 5590 /* Interior cells add new cells, faces, edges, and vertex */ 5591 for (r = 0; r < 8; ++r, ++m) { 5592 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5593 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5594 remotePointsNew[m].rank = rrank; 5595 } 5596 for (r = 0; r < 12; ++r, ++m) { 5597 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 5598 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 5599 remotePointsNew[m].rank = rrank; 5600 } 5601 for (r = 0; r < 6; ++r, ++m) { 5602 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 5603 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; 5604 remotePointsNew[m].rank = rrank; 5605 } 5606 for (r = 0; r < 1; ++r, ++m) { 5607 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 5608 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 5609 remotePointsNew[m].rank = rrank; 5610 } 5611 } else if ((p >= cMax) && (p < cEnd)) { 5612 /* Hybrid cells add new cells, faces, and edges */ 5613 for (r = 0; r < 4; ++r, ++m) { 5614 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5615 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5616 remotePointsNew[m].rank = rrank; 5617 } 5618 for (r = 0; r < 4; ++r, ++m) { 5619 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 5620 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; 5621 remotePointsNew[m].rank = rrank; 5622 } 5623 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 5624 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]); 5625 remotePointsNew[m].rank = rrank; 5626 ++m; 5627 } 5628 break; 5629 default: 5630 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5631 } 5632 } 5633 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 5634 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 5635 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 5636 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5637 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 5638 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 5639 PetscFunctionReturn(0); 5640 } 5641 5642 #undef __FUNCT__ 5643 #define __FUNCT__ "CellRefinerCreateLabels" 5644 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5645 { 5646 PetscInt numLabels, l; 5647 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 5648 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5649 PetscErrorCode ierr; 5650 5651 PetscFunctionBegin; 5652 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5653 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5654 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5655 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5656 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5657 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5658 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 5659 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5660 switch (refiner) { 5661 case 0: break; 5662 case 7: 5663 case 8: 5664 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 5665 case 3: 5666 case 4: 5667 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 5668 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5669 } 5670 for (l = 0; l < numLabels; ++l) { 5671 DMLabel label, labelNew; 5672 const char *lname; 5673 PetscBool isDepth; 5674 IS valueIS; 5675 const PetscInt *values; 5676 PetscInt numValues, val; 5677 5678 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 5679 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 5680 if (isDepth) continue; 5681 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 5682 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 5683 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 5684 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 5685 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 5686 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 5687 for (val = 0; val < numValues; ++val) { 5688 IS pointIS; 5689 const PetscInt *points; 5690 PetscInt numPoints, n; 5691 5692 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 5693 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 5694 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 5695 for (n = 0; n < numPoints; ++n) { 5696 const PetscInt p = points[n]; 5697 switch (refiner) { 5698 case 1: 5699 /* Simplicial 2D */ 5700 if ((p >= vStart) && (p < vEnd)) { 5701 /* Old vertices stay the same */ 5702 newp = vStartNew + (p - vStart); 5703 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5704 } else if ((p >= fStart) && (p < fEnd)) { 5705 /* Old faces add new faces and vertex */ 5706 newp = vStartNew + (vEnd - vStart) + (p - fStart); 5707 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5708 for (r = 0; r < 2; ++r) { 5709 newp = fStartNew + (p - fStart)*2 + r; 5710 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5711 } 5712 } else if ((p >= cStart) && (p < cEnd)) { 5713 /* Old cells add new cells and interior faces */ 5714 for (r = 0; r < 4; ++r) { 5715 newp = cStartNew + (p - cStart)*4 + r; 5716 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5717 } 5718 for (r = 0; r < 3; ++r) { 5719 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5720 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5721 } 5722 } 5723 break; 5724 case 2: 5725 /* Hex 2D */ 5726 if ((p >= vStart) && (p < vEnd)) { 5727 /* Old vertices stay the same */ 5728 newp = vStartNew + (p - vStart); 5729 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5730 } else if ((p >= fStart) && (p < fEnd)) { 5731 /* Old faces add new faces and vertex */ 5732 newp = vStartNew + (vEnd - vStart) + (p - fStart); 5733 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5734 for (r = 0; r < 2; ++r) { 5735 newp = fStartNew + (p - fStart)*2 + r; 5736 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5737 } 5738 } else if ((p >= cStart) && (p < cEnd)) { 5739 /* Old cells add new cells and interior faces and vertex */ 5740 for (r = 0; r < 4; ++r) { 5741 newp = cStartNew + (p - cStart)*4 + r; 5742 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5743 } 5744 for (r = 0; r < 4; ++r) { 5745 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 5746 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5747 } 5748 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 5749 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5750 } 5751 break; 5752 case 3: 5753 /* Hybrid simplicial 2D */ 5754 if ((p >= vStart) && (p < vEnd)) { 5755 /* Old vertices stay the same */ 5756 newp = vStartNew + (p - vStart); 5757 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5758 } else if ((p >= fStart) && (p < fMax)) { 5759 /* Old interior faces add new faces and vertex */ 5760 newp = vStartNew + (vEnd - vStart) + (p - fStart); 5761 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5762 for (r = 0; r < 2; ++r) { 5763 newp = fStartNew + (p - fStart)*2 + r; 5764 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5765 } 5766 } else if ((p >= fMax) && (p < fEnd)) { 5767 /* Old hybrid faces stay the same */ 5768 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 5769 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5770 } else if ((p >= cStart) && (p < cMax)) { 5771 /* Old interior cells add new cells and interior faces */ 5772 for (r = 0; r < 4; ++r) { 5773 newp = cStartNew + (p - cStart)*4 + r; 5774 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5775 } 5776 for (r = 0; r < 3; ++r) { 5777 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5778 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5779 } 5780 } else if ((p >= cMax) && (p < cEnd)) { 5781 /* Old hybrid cells add new cells and hybrid face */ 5782 for (r = 0; r < 2; ++r) { 5783 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 5784 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5785 } 5786 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5787 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5788 } 5789 break; 5790 case 5: 5791 /* Simplicial 3D */ 5792 if ((p >= vStart) && (p < vEnd)) { 5793 /* Old vertices stay the same */ 5794 newp = vStartNew + (p - vStart); 5795 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5796 } else if ((p >= eStart) && (p < eEnd)) { 5797 /* Old edges add new edges and vertex */ 5798 for (r = 0; r < 2; ++r) { 5799 newp = eStartNew + (p - eStart)*2 + r; 5800 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5801 } 5802 newp = vStartNew + (vEnd - vStart) + (p - eStart); 5803 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5804 } else if ((p >= fStart) && (p < fEnd)) { 5805 /* Old faces add new faces and edges */ 5806 for (r = 0; r < 4; ++r) { 5807 newp = fStartNew + (p - fStart)*4 + r; 5808 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5809 } 5810 for (r = 0; r < 3; ++r) { 5811 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 5812 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5813 } 5814 } else if ((p >= cStart) && (p < cEnd)) { 5815 /* Old cells add new cells and interior faces and edges */ 5816 for (r = 0; r < 8; ++r) { 5817 newp = cStartNew + (p - cStart)*8 + r; 5818 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5819 } 5820 for (r = 0; r < 8; ++r) { 5821 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 5822 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5823 } 5824 for (r = 0; r < 1; ++r) { 5825 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 5826 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5827 } 5828 } 5829 break; 5830 case 7: 5831 /* Hybrid Simplicial 3D */ 5832 if ((p >= vStart) && (p < vEnd)) { 5833 /* Interior vertices stay the same */ 5834 newp = vStartNew + (p - vStart); 5835 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5836 } else if ((p >= eStart) && (p < eMax)) { 5837 /* Interior edges add new edges and vertex */ 5838 for (r = 0; r < 2; ++r) { 5839 newp = eStartNew + (p - eStart)*2 + r; 5840 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5841 } 5842 newp = vStartNew + (vEnd - vStart) + (p - eStart); 5843 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5844 } else if ((p >= eMax) && (p < eEnd)) { 5845 /* Hybrid edges stay the same */ 5846 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5847 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5848 } else if ((p >= fStart) && (p < fMax)) { 5849 /* Interior faces add new faces and edges */ 5850 for (r = 0; r < 4; ++r) { 5851 newp = fStartNew + (p - fStart)*4 + r; 5852 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5853 } 5854 for (r = 0; r < 3; ++r) { 5855 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5856 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5857 } 5858 } else if ((p >= fMax) && (p < fEnd)) { 5859 /* Hybrid faces add new faces and edges */ 5860 for (r = 0; r < 2; ++r) { 5861 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5862 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5863 } 5864 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 5865 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5866 } else if ((p >= cStart) && (p < cMax)) { 5867 /* Interior cells add new cells, faces, and edges */ 5868 for (r = 0; r < 8; ++r) { 5869 newp = cStartNew + (p - cStart)*8 + r; 5870 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5871 } 5872 for (r = 0; r < 8; ++r) { 5873 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5874 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5875 } 5876 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 5877 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5878 } else if ((p >= cMax) && (p < cEnd)) { 5879 /* Hybrid cells add new cells and faces */ 5880 for (r = 0; r < 4; ++r) { 5881 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5882 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5883 } 5884 for (r = 0; r < 3; ++r) { 5885 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5886 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5887 } 5888 } 5889 break; 5890 case 6: 5891 /* Hex 3D */ 5892 if ((p >= vStart) && (p < vEnd)) { 5893 /* Old vertices stay the same */ 5894 newp = vStartNew + (p - vStart); 5895 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5896 } else if ((p >= eStart) && (p < eEnd)) { 5897 /* Old edges add new edges and vertex */ 5898 for (r = 0; r < 2; ++r) { 5899 newp = eStartNew + (p - eStart)*2 + r; 5900 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5901 } 5902 newp = vStartNew + (vEnd - vStart) + (p - eStart); 5903 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5904 } else if ((p >= fStart) && (p < fEnd)) { 5905 /* Old faces add new faces, edges, and vertex */ 5906 for (r = 0; r < 4; ++r) { 5907 newp = fStartNew + (p - fStart)*4 + r; 5908 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5909 } 5910 for (r = 0; r < 4; ++r) { 5911 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 5912 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5913 } 5914 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 5915 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5916 } else if ((p >= cStart) && (p < cEnd)) { 5917 /* Old cells add new cells, faces, edges, and vertex */ 5918 for (r = 0; r < 8; ++r) { 5919 newp = cStartNew + (p - cStart)*8 + r; 5920 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5921 } 5922 for (r = 0; r < 12; ++r) { 5923 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 5924 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5925 } 5926 for (r = 0; r < 6; ++r) { 5927 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 5928 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5929 } 5930 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 5931 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5932 } 5933 break; 5934 case 8: 5935 /* Hybrid Hex 3D */ 5936 if ((p >= vStart) && (p < vEnd)) { 5937 /* Interior vertices stay the same */ 5938 newp = vStartNew + (p - vStart); 5939 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5940 } else if ((p >= eStart) && (p < eMax)) { 5941 /* Interior edges add new edges and vertex */ 5942 for (r = 0; r < 2; ++r) { 5943 newp = eStartNew + (p - eStart)*2 + r; 5944 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5945 } 5946 newp = vStartNew + (vEnd - vStart) + (p - eStart); 5947 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5948 } else if ((p >= eMax) && (p < eEnd)) { 5949 /* Hybrid edges stay the same */ 5950 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 5951 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5952 } else if ((p >= fStart) && (p < fMax)) { 5953 /* Interior faces add new faces, edges, and vertex */ 5954 for (r = 0; r < 4; ++r) { 5955 newp = fStartNew + (p - fStart)*4 + r; 5956 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5957 } 5958 for (r = 0; r < 4; ++r) { 5959 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 5960 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5961 } 5962 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 5963 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5964 } else if ((p >= fMax) && (p < fEnd)) { 5965 /* Hybrid faces add new faces and edges */ 5966 for (r = 0; r < 2; ++r) { 5967 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 5968 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5969 } 5970 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 5971 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5972 } else if ((p >= cStart) && (p < cMax)) { 5973 /* Interior cells add new cells, faces, edges, and vertex */ 5974 for (r = 0; r < 8; ++r) { 5975 newp = cStartNew + (p - cStart)*8 + r; 5976 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5977 } 5978 for (r = 0; r < 12; ++r) { 5979 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 5980 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5981 } 5982 for (r = 0; r < 6; ++r) { 5983 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 5984 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5985 } 5986 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 5987 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5988 } else if ((p >= cMax) && (p < cEnd)) { 5989 /* Hybrid cells add new cells, faces, and edges */ 5990 for (r = 0; r < 4; ++r) { 5991 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5992 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5993 } 5994 for (r = 0; r < 4; ++r) { 5995 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 5996 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 5997 } 5998 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 5999 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6000 } 6001 break; 6002 default: 6003 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6004 } 6005 } 6006 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6007 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6008 } 6009 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6010 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6011 if (0) { 6012 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6013 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6014 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6015 } 6016 } 6017 PetscFunctionReturn(0); 6018 } 6019 6020 #undef __FUNCT__ 6021 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6022 /* This will only work for interpolated meshes */ 6023 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6024 { 6025 DM rdm; 6026 PetscInt *depthSize; 6027 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6028 PetscErrorCode ierr; 6029 6030 PetscFunctionBegin; 6031 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6032 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6033 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6034 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 6035 /* Calculate number of new points of each depth */ 6036 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6037 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6038 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6039 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6040 /* Step 1: Set chart */ 6041 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6042 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6043 /* Step 2: Set cone/support sizes */ 6044 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6045 /* Step 3: Setup refined DM */ 6046 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6047 /* Step 4: Set cones and supports */ 6048 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6049 /* Step 5: Stratify */ 6050 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6051 /* Step 6: Set coordinates for vertices */ 6052 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6053 /* Step 7: Create pointSF */ 6054 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6055 /* Step 8: Create labels */ 6056 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6057 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6058 6059 *dmRefined = rdm; 6060 PetscFunctionReturn(0); 6061 } 6062 6063 #undef __FUNCT__ 6064 #define __FUNCT__ "DMPlexSetRefinementUniform" 6065 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6066 { 6067 DM_Plex *mesh = (DM_Plex*) dm->data; 6068 6069 PetscFunctionBegin; 6070 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6071 mesh->refinementUniform = refinementUniform; 6072 PetscFunctionReturn(0); 6073 } 6074 6075 #undef __FUNCT__ 6076 #define __FUNCT__ "DMPlexGetRefinementUniform" 6077 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6078 { 6079 DM_Plex *mesh = (DM_Plex*) dm->data; 6080 6081 PetscFunctionBegin; 6082 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6083 PetscValidPointer(refinementUniform, 2); 6084 *refinementUniform = mesh->refinementUniform; 6085 PetscFunctionReturn(0); 6086 } 6087 6088 #undef __FUNCT__ 6089 #define __FUNCT__ "DMPlexSetRefinementLimit" 6090 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6091 { 6092 DM_Plex *mesh = (DM_Plex*) dm->data; 6093 6094 PetscFunctionBegin; 6095 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6096 mesh->refinementLimit = refinementLimit; 6097 PetscFunctionReturn(0); 6098 } 6099 6100 #undef __FUNCT__ 6101 #define __FUNCT__ "DMPlexGetRefinementLimit" 6102 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6103 { 6104 DM_Plex *mesh = (DM_Plex*) dm->data; 6105 6106 PetscFunctionBegin; 6107 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6108 PetscValidPointer(refinementLimit, 2); 6109 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6110 *refinementLimit = mesh->refinementLimit; 6111 PetscFunctionReturn(0); 6112 } 6113 6114 #undef __FUNCT__ 6115 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6116 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6117 { 6118 PetscInt dim, cStart, cEnd, coneSize, cMax; 6119 PetscErrorCode ierr; 6120 6121 PetscFunctionBegin; 6122 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6123 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6124 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 6125 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6126 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6127 switch (dim) { 6128 case 2: 6129 switch (coneSize) { 6130 case 3: 6131 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 6132 else *cellRefiner = 1; /* Triangular */ 6133 break; 6134 case 4: 6135 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 6136 else *cellRefiner = 2; /* Quadrilateral */ 6137 break; 6138 default: 6139 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6140 } 6141 break; 6142 case 3: 6143 switch (coneSize) { 6144 case 4: 6145 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 6146 else *cellRefiner = 5; /* Tetrahedral */ 6147 break; 6148 case 6: 6149 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 6150 else *cellRefiner = 6; /* hexahedral */ 6151 break; 6152 default: 6153 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6154 } 6155 break; 6156 default: 6157 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6158 } 6159 PetscFunctionReturn(0); 6160 } 6161