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 = depth < 0 ? 0 : depthSize[depth]; 11 if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 12 if (eStart) *eStart = depth < 0 ? 0 : 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 = depth < 0 ? 0 : depthSize[depth]; 22 if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 23 if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 24 if (eEnd) *eEnd = depth < 0 ? 0 : 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 /* 42 2 43 |\ 44 | \ 45 | \ 46 | \ 47 | C \ 48 | \ 49 | \ 50 2---1---1 51 |\ D / \ 52 | 2 0 \ 53 |A \ / B \ 54 0---0-------1 55 */ 56 dim = 2; 57 if (numSubcells) *numSubcells = 4; 58 if (v0) { 59 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 60 /* A */ 61 v[0+0] = -1.0; v[0+1] = -1.0; 62 j[0+0] = 0.5; j[0+1] = 0.0; 63 j[0+2] = 0.0; j[0+3] = 0.5; 64 /* B */ 65 v[2+0] = 0.0; v[2+1] = -1.0; 66 j[4+0] = 0.5; j[4+1] = 0.0; 67 j[4+2] = 0.0; j[4+3] = 0.5; 68 /* C */ 69 v[4+0] = -1.0; v[4+1] = 0.0; 70 j[8+0] = 0.5; j[8+1] = 0.0; 71 j[8+2] = 0.0; j[8+3] = 0.5; 72 /* D */ 73 v[6+0] = 0.0; v[6+1] = -1.0; 74 j[12+0] = 0.0; j[12+1] = -0.5; 75 j[12+2] = 0.5; j[12+3] = 0.5; 76 for (s = 0; s < 4; ++s) { 77 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 78 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 79 } 80 } 81 break; 82 case 2: 83 /* 84 3---------2---------2 85 | | | 86 | D 2 C | 87 | | | 88 3----3----0----1----1 89 | | | 90 | A 0 B | 91 | | | 92 0---------0---------1 93 */ 94 dim = 2; 95 if (numSubcells) *numSubcells = 4; 96 if (v0) { 97 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 98 /* A */ 99 v[0+0] = -1.0; v[0+1] = -1.0; 100 j[0+0] = 0.5; j[0+1] = 0.0; 101 j[0+2] = 0.0; j[0+3] = 0.5; 102 /* B */ 103 v[2+0] = 0.0; v[2+1] = -1.0; 104 j[4+0] = 0.5; j[4+1] = 0.0; 105 j[4+2] = 0.0; j[4+3] = 0.5; 106 /* C */ 107 v[4+0] = 0.0; v[4+1] = 0.0; 108 j[8+0] = 0.5; j[8+1] = 0.0; 109 j[8+2] = 0.0; j[8+3] = 0.5; 110 /* D */ 111 v[6+0] = -1.0; v[6+1] = 0.0; 112 j[12+0] = 0.5; j[12+1] = 0.0; 113 j[12+2] = 0.0; j[12+3] = 0.5; 114 for (s = 0; s < 4; ++s) { 115 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 116 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 117 } 118 } 119 break; 120 default: 121 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 122 } 123 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 124 PetscFunctionReturn(0); 125 } 126 127 #undef __FUNCT__ 128 #define __FUNCT__ "CellRefinerRestoreAffineTransforms_Internal" 129 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 130 { 131 PetscErrorCode ierr; 132 133 PetscFunctionBegin; 134 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 135 PetscFunctionReturn(0); 136 } 137 138 #undef __FUNCT__ 139 #define __FUNCT__ "CellRefinerInCellTest_Internal" 140 /* Should this be here or in the DualSpace somehow? */ 141 PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside) 142 { 143 PetscReal sum = 0.0; 144 PetscInt d; 145 146 PetscFunctionBegin; 147 *inside = PETSC_TRUE; 148 switch (refiner) { 149 case 0: break; 150 case 1: 151 for (d = 0; d < 2; ++d) { 152 if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 153 sum += point[d]; 154 } 155 if (sum > 0.0) {*inside = PETSC_FALSE; break;} 156 break; 157 case 2: 158 for (d = 0; d < 2; ++d) if ((point[d] < -1.0) || (point[d] > 1.0)) {*inside = PETSC_FALSE; break;} 159 break; 160 default: 161 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 162 } 163 PetscFunctionReturn(0); 164 } 165 166 #undef __FUNCT__ 167 #define __FUNCT__ "CellRefinerGetSizes" 168 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 169 { 170 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 171 PetscErrorCode ierr; 172 173 PetscFunctionBegin; 174 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 175 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 176 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 177 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 178 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 179 switch (refiner) { 180 case 0: 181 break; 182 case 1: 183 /* Simplicial 2D */ 184 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 185 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 186 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 187 break; 188 case 3: 189 /* Hybrid Simplicial 2D */ 190 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 191 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 192 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 193 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 */ 194 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 195 break; 196 case 2: 197 /* Hex 2D */ 198 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 199 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 200 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 201 break; 202 case 4: 203 /* Hybrid Hex 2D */ 204 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 205 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 206 /* Quadrilateral */ 207 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 208 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 209 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 210 /* Segment Prisms */ 211 depthSize[0] += 0; /* No hybrid vertices */ 212 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 213 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 214 break; 215 case 5: 216 /* Simplicial 3D */ 217 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 218 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 */ 219 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 220 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 221 break; 222 case 7: 223 /* Hybrid Simplicial 3D */ 224 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 225 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 226 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 227 /* Tetrahedra */ 228 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 229 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 */ 230 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 231 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 232 /* Triangular Prisms */ 233 depthSize[0] += 0; /* No hybrid vertices */ 234 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 235 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 236 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 237 break; 238 case 6: 239 /* Hex 3D */ 240 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 241 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 */ 242 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 243 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 244 break; 245 case 8: 246 /* Hybrid Hex 3D */ 247 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 248 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 249 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 250 /* Hexahedra */ 251 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 252 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 */ 253 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 254 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 255 /* Quadrilateral Prisms */ 256 depthSize[0] += 0; /* No hybrid vertices */ 257 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 258 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 259 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 260 break; 261 default: 262 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 263 } 264 PetscFunctionReturn(0); 265 } 266 267 /* Return triangle edge for orientation o, if it is r for o == 0 */ 268 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 269 return (o < 0 ? 2-(o+r) : o+r)%3; 270 } 271 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 272 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 273 } 274 275 /* Return triangle subface for orientation o, if it is r for o == 0 */ 276 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 277 return (o < 0 ? 3-(o+r) : o+r)%3; 278 } 279 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 280 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 281 } 282 283 /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */ 284 PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) { 285 return (o < 0 ? 1-(o+r) : o+r)%3; 286 } 287 PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) { 288 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 289 } 290 291 292 /* Return quad edge for orientation o, if it is r for o == 0 */ 293 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 294 return (o < 0 ? 3-(o+r) : o+r)%4; 295 } 296 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 297 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 298 } 299 300 /* Return quad subface for orientation o, if it is r for o == 0 */ 301 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 302 return (o < 0 ? 4-(o+r) : o+r)%4; 303 } 304 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 305 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 306 } 307 308 #undef __FUNCT__ 309 #define __FUNCT__ "CellRefinerSetConeSizes" 310 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 311 { 312 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 313 PetscErrorCode ierr; 314 315 PetscFunctionBegin; 316 if (!refiner) PetscFunctionReturn(0); 317 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 318 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 319 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 320 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 321 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 322 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 323 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 324 switch (refiner) { 325 case 1: 326 /* Simplicial 2D */ 327 /* All cells have 3 faces */ 328 for (c = cStart; c < cEnd; ++c) { 329 for (r = 0; r < 4; ++r) { 330 const PetscInt newp = (c - cStart)*4 + r; 331 332 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 333 } 334 } 335 /* Split faces have 2 vertices and the same cells as the parent */ 336 for (f = fStart; f < fEnd; ++f) { 337 for (r = 0; r < 2; ++r) { 338 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 339 PetscInt size; 340 341 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 342 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 343 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 344 } 345 } 346 /* Interior faces have 2 vertices and 2 cells */ 347 for (c = cStart; c < cEnd; ++c) { 348 for (r = 0; r < 3; ++r) { 349 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 350 351 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 352 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 353 } 354 } 355 /* Old vertices have identical supports */ 356 for (v = vStart; v < vEnd; ++v) { 357 const PetscInt newp = vStartNew + (v - vStart); 358 PetscInt size; 359 360 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 361 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 362 } 363 /* Face vertices have 2 + cells*2 supports */ 364 for (f = fStart; f < fEnd; ++f) { 365 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 366 PetscInt size; 367 368 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 369 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 370 } 371 break; 372 case 2: 373 /* Hex 2D */ 374 /* All cells have 4 faces */ 375 for (c = cStart; c < cEnd; ++c) { 376 for (r = 0; r < 4; ++r) { 377 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 378 379 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 380 } 381 } 382 /* Split faces have 2 vertices and the same cells as the parent */ 383 for (f = fStart; f < fEnd; ++f) { 384 for (r = 0; r < 2; ++r) { 385 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 386 PetscInt size; 387 388 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 389 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 390 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 391 } 392 } 393 /* Interior faces have 2 vertices and 2 cells */ 394 for (c = cStart; c < cEnd; ++c) { 395 for (r = 0; r < 4; ++r) { 396 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 397 398 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 399 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 400 } 401 } 402 /* Old vertices have identical supports */ 403 for (v = vStart; v < vEnd; ++v) { 404 const PetscInt newp = vStartNew + (v - vStart); 405 PetscInt size; 406 407 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 408 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 409 } 410 /* Face vertices have 2 + cells supports */ 411 for (f = fStart; f < fEnd; ++f) { 412 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 413 PetscInt size; 414 415 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 416 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 417 } 418 /* Cell vertices have 4 supports */ 419 for (c = cStart; c < cEnd; ++c) { 420 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 421 422 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 423 } 424 break; 425 case 3: 426 /* Hybrid Simplicial 2D */ 427 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 428 cMax = PetscMin(cEnd, cMax); 429 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 430 fMax = PetscMin(fEnd, fMax); 431 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 432 /* Interior cells have 3 faces */ 433 for (c = cStart; c < cMax; ++c) { 434 for (r = 0; r < 4; ++r) { 435 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 436 437 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 438 } 439 } 440 /* Hybrid cells have 4 faces */ 441 for (c = cMax; c < cEnd; ++c) { 442 for (r = 0; r < 2; ++r) { 443 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 444 445 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 446 } 447 } 448 /* Interior split faces have 2 vertices and the same cells as the parent */ 449 for (f = fStart; f < fMax; ++f) { 450 for (r = 0; r < 2; ++r) { 451 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 452 PetscInt size; 453 454 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 455 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 456 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 457 } 458 } 459 /* Interior cell faces have 2 vertices and 2 cells */ 460 for (c = cStart; c < cMax; ++c) { 461 for (r = 0; r < 3; ++r) { 462 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 463 464 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 465 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 466 } 467 } 468 /* Hybrid faces have 2 vertices and the same cells */ 469 for (f = fMax; f < fEnd; ++f) { 470 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 471 PetscInt size; 472 473 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 474 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 475 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 476 } 477 /* Hybrid cell faces have 2 vertices and 2 cells */ 478 for (c = cMax; c < cEnd; ++c) { 479 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 480 481 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 482 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 483 } 484 /* Old vertices have identical supports */ 485 for (v = vStart; v < vEnd; ++v) { 486 const PetscInt newp = vStartNew + (v - vStart); 487 PetscInt size; 488 489 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 490 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 491 } 492 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 493 for (f = fStart; f < fMax; ++f) { 494 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 495 const PetscInt *support; 496 PetscInt size, newSize = 2, s; 497 498 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 499 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 500 for (s = 0; s < size; ++s) { 501 if (support[s] >= cMax) newSize += 1; 502 else newSize += 2; 503 } 504 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 505 } 506 break; 507 case 4: 508 /* Hybrid Hex 2D */ 509 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 510 cMax = PetscMin(cEnd, cMax); 511 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 512 fMax = PetscMin(fEnd, fMax); 513 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 514 /* Interior cells have 4 faces */ 515 for (c = cStart; c < cMax; ++c) { 516 for (r = 0; r < 4; ++r) { 517 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 518 519 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 520 } 521 } 522 /* Hybrid cells have 4 faces */ 523 for (c = cMax; c < cEnd; ++c) { 524 for (r = 0; r < 2; ++r) { 525 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 526 527 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 528 } 529 } 530 /* Interior split faces have 2 vertices and the same cells as the parent */ 531 for (f = fStart; f < fMax; ++f) { 532 for (r = 0; r < 2; ++r) { 533 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 534 PetscInt size; 535 536 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 537 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 538 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 539 } 540 } 541 /* Interior cell faces have 2 vertices and 2 cells */ 542 for (c = cStart; c < cMax; ++c) { 543 for (r = 0; r < 4; ++r) { 544 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 545 546 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 547 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 548 } 549 } 550 /* Hybrid faces have 2 vertices and the same cells */ 551 for (f = fMax; f < fEnd; ++f) { 552 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 553 PetscInt size; 554 555 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 556 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 557 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 558 } 559 /* Hybrid cell faces have 2 vertices and 2 cells */ 560 for (c = cMax; c < cEnd; ++c) { 561 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 562 563 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 564 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 565 } 566 /* Old vertices have identical supports */ 567 for (v = vStart; v < vEnd; ++v) { 568 const PetscInt newp = vStartNew + (v - vStart); 569 PetscInt size; 570 571 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 572 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 573 } 574 /* Face vertices have 2 + cells supports */ 575 for (f = fStart; f < fMax; ++f) { 576 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 577 PetscInt size; 578 579 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 580 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 581 } 582 /* Cell vertices have 4 supports */ 583 for (c = cStart; c < cMax; ++c) { 584 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 585 586 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 587 } 588 break; 589 case 5: 590 /* Simplicial 3D */ 591 /* All cells have 4 faces */ 592 for (c = cStart; c < cEnd; ++c) { 593 for (r = 0; r < 8; ++r) { 594 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 595 596 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 597 } 598 } 599 /* Split faces have 3 edges and the same cells as the parent */ 600 for (f = fStart; f < fEnd; ++f) { 601 for (r = 0; r < 4; ++r) { 602 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 603 PetscInt size; 604 605 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 606 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 607 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 608 } 609 } 610 /* Interior cell faces have 3 edges and 2 cells */ 611 for (c = cStart; c < cEnd; ++c) { 612 for (r = 0; r < 8; ++r) { 613 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 614 615 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 616 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 617 } 618 } 619 /* Split edges have 2 vertices and the same faces */ 620 for (e = eStart; e < eEnd; ++e) { 621 for (r = 0; r < 2; ++r) { 622 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 623 PetscInt size; 624 625 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 626 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 627 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 628 } 629 } 630 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 631 for (f = fStart; f < fEnd; ++f) { 632 for (r = 0; r < 3; ++r) { 633 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 634 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 635 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 636 637 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 638 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 639 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 640 for (s = 0; s < supportSize; ++s) { 641 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 642 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 643 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 644 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 645 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 646 er = GetTetSomethingInverse_Static(ornt[c], r); 647 if (er == eint[c]) { 648 intFaces += 1; 649 } else { 650 intFaces += 2; 651 } 652 } 653 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 654 } 655 } 656 /* Interior cell edges have 2 vertices and 4 faces */ 657 for (c = cStart; c < cEnd; ++c) { 658 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 659 660 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 661 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 662 } 663 /* Old vertices have identical supports */ 664 for (v = vStart; v < vEnd; ++v) { 665 const PetscInt newp = vStartNew + (v - vStart); 666 PetscInt size; 667 668 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 669 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 670 } 671 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 672 for (e = eStart; e < eEnd; ++e) { 673 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 674 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 675 676 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 677 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 678 for (s = 0; s < starSize*2; s += 2) { 679 const PetscInt *cone, *ornt; 680 PetscInt e01, e23; 681 682 if ((star[s] >= cStart) && (star[s] < cEnd)) { 683 /* Check edge 0-1 */ 684 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 685 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 686 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 687 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 688 /* Check edge 2-3 */ 689 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 690 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 691 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 692 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 693 if ((e01 == e) || (e23 == e)) ++cellSize; 694 } 695 } 696 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 697 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 698 } 699 break; 700 case 7: 701 /* Hybrid Simplicial 3D */ 702 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 703 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 704 /* Interior cells have 4 faces */ 705 for (c = cStart; c < cMax; ++c) { 706 for (r = 0; r < 8; ++r) { 707 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 708 709 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 710 } 711 } 712 /* Hybrid cells have 5 faces */ 713 for (c = cMax; c < cEnd; ++c) { 714 for (r = 0; r < 4; ++r) { 715 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 716 717 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 718 } 719 } 720 /* Interior split faces have 3 edges and the same cells as the parent */ 721 for (f = fStart; f < fMax; ++f) { 722 for (r = 0; r < 4; ++r) { 723 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 724 PetscInt size; 725 726 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 727 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 728 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 729 } 730 } 731 /* Interior cell faces have 3 edges and 2 cells */ 732 for (c = cStart; c < cMax; ++c) { 733 for (r = 0; r < 8; ++r) { 734 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 735 736 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 737 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 738 } 739 } 740 /* Hybrid split faces have 4 edges and the same cells as the parent */ 741 for (f = fMax; f < fEnd; ++f) { 742 for (r = 0; r < 2; ++r) { 743 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 744 PetscInt size; 745 746 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 747 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 748 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 749 } 750 } 751 /* Hybrid cells faces have 4 edges and 2 cells */ 752 for (c = cMax; c < cEnd; ++c) { 753 for (r = 0; r < 3; ++r) { 754 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 755 756 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 757 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 758 } 759 } 760 /* Interior split edges have 2 vertices and the same faces */ 761 for (e = eStart; e < eMax; ++e) { 762 for (r = 0; r < 2; ++r) { 763 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 764 PetscInt size; 765 766 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 767 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 768 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 769 } 770 } 771 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 772 for (f = fStart; f < fMax; ++f) { 773 for (r = 0; r < 3; ++r) { 774 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 775 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 776 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 777 778 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 779 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 780 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 781 for (s = 0; s < supportSize; ++s) { 782 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 783 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 784 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 785 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 786 if (support[s] < cMax) { 787 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 788 er = GetTetSomethingInverse_Static(ornt[c], r); 789 if (er == eint[c]) { 790 intFaces += 1; 791 } else { 792 intFaces += 2; 793 } 794 } else { 795 intFaces += 1; 796 } 797 } 798 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 799 } 800 } 801 /* Interior cell edges have 2 vertices and 4 faces */ 802 for (c = cStart; c < cMax; ++c) { 803 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 804 805 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 806 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 807 } 808 /* Hybrid edges have 2 vertices and the same faces */ 809 for (e = eMax; e < eEnd; ++e) { 810 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 811 PetscInt size; 812 813 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 814 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 815 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 816 } 817 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 818 for (f = fMax; f < fEnd; ++f) { 819 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 820 PetscInt size; 821 822 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 823 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 824 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 825 } 826 /* Interior vertices have identical supports */ 827 for (v = vStart; v < vEnd; ++v) { 828 const PetscInt newp = vStartNew + (v - vStart); 829 PetscInt size; 830 831 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 832 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 833 } 834 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 835 for (e = eStart; e < eMax; ++e) { 836 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 837 const PetscInt *support; 838 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 839 840 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 841 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 842 for (s = 0; s < size; ++s) { 843 if (support[s] < fMax) faceSize += 2; 844 else faceSize += 1; 845 } 846 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 847 for (s = 0; s < starSize*2; s += 2) { 848 const PetscInt *cone, *ornt; 849 PetscInt e01, e23; 850 851 if ((star[s] >= cStart) && (star[s] < cMax)) { 852 /* Check edge 0-1 */ 853 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 854 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 855 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 856 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 857 /* Check edge 2-3 */ 858 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 859 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 860 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 861 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 862 if ((e01 == e) || (e23 == e)) ++cellSize; 863 } 864 } 865 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 866 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 867 } 868 break; 869 case 6: 870 /* Hex 3D */ 871 /* All cells have 6 faces */ 872 for (c = cStart; c < cEnd; ++c) { 873 for (r = 0; r < 8; ++r) { 874 const PetscInt newp = (c - cStart)*8 + r; 875 876 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 877 } 878 } 879 /* Split faces have 4 edges and the same cells as the parent */ 880 for (f = fStart; f < fEnd; ++f) { 881 for (r = 0; r < 4; ++r) { 882 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 883 PetscInt size; 884 885 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 886 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 887 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 888 } 889 } 890 /* Interior faces have 4 edges and 2 cells */ 891 for (c = cStart; c < cEnd; ++c) { 892 for (r = 0; r < 12; ++r) { 893 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 894 895 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 896 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 897 } 898 } 899 /* Split edges have 2 vertices and the same faces as the parent */ 900 for (e = eStart; e < eEnd; ++e) { 901 for (r = 0; r < 2; ++r) { 902 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 903 PetscInt size; 904 905 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 906 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 907 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 908 } 909 } 910 /* Face edges have 2 vertices and 2+cells faces */ 911 for (f = fStart; f < fEnd; ++f) { 912 for (r = 0; r < 4; ++r) { 913 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 914 PetscInt size; 915 916 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 917 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 918 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 919 } 920 } 921 /* Cell edges have 2 vertices and 4 faces */ 922 for (c = cStart; c < cEnd; ++c) { 923 for (r = 0; r < 6; ++r) { 924 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 925 926 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 927 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 928 } 929 } 930 /* Old vertices have identical supports */ 931 for (v = vStart; v < vEnd; ++v) { 932 const PetscInt newp = vStartNew + (v - vStart); 933 PetscInt size; 934 935 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 936 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 937 } 938 /* Edge vertices have 2 + faces supports */ 939 for (e = eStart; e < eEnd; ++e) { 940 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 941 PetscInt size; 942 943 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 944 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 945 } 946 /* Face vertices have 4 + cells supports */ 947 for (f = fStart; f < fEnd; ++f) { 948 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 949 PetscInt size; 950 951 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 952 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 953 } 954 /* Cell vertices have 6 supports */ 955 for (c = cStart; c < cEnd; ++c) { 956 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 957 958 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 959 } 960 break; 961 case 8: 962 /* Hybrid Hex 3D */ 963 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 964 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 965 /* Interior cells have 6 faces */ 966 for (c = cStart; c < cMax; ++c) { 967 for (r = 0; r < 8; ++r) { 968 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 969 970 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 971 } 972 } 973 /* Hybrid cells have 6 faces */ 974 for (c = cMax; c < cEnd; ++c) { 975 for (r = 0; r < 4; ++r) { 976 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 977 978 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 979 } 980 } 981 /* Interior split faces have 4 edges and the same cells as the parent */ 982 for (f = fStart; f < fMax; ++f) { 983 for (r = 0; r < 4; ++r) { 984 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 985 PetscInt size; 986 987 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 988 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 989 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 990 } 991 } 992 /* Interior cell faces have 4 edges and 2 cells */ 993 for (c = cStart; c < cMax; ++c) { 994 for (r = 0; r < 12; ++r) { 995 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 996 997 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 998 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 999 } 1000 } 1001 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1002 for (f = fMax; f < fEnd; ++f) { 1003 for (r = 0; r < 2; ++r) { 1004 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1005 PetscInt size; 1006 1007 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1008 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1009 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1010 } 1011 } 1012 /* Hybrid cells faces have 4 edges and 2 cells */ 1013 for (c = cMax; c < cEnd; ++c) { 1014 for (r = 0; r < 4; ++r) { 1015 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1016 1017 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1018 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1019 } 1020 } 1021 /* Interior split edges have 2 vertices and the same faces as the parent */ 1022 for (e = eStart; e < eMax; ++e) { 1023 for (r = 0; r < 2; ++r) { 1024 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1025 PetscInt size; 1026 1027 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1028 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1029 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1030 } 1031 } 1032 /* Interior face edges have 2 vertices and 2+cells faces */ 1033 for (f = fStart; f < fMax; ++f) { 1034 for (r = 0; r < 4; ++r) { 1035 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1036 PetscInt size; 1037 1038 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1039 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1040 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1041 } 1042 } 1043 /* Interior cell edges have 2 vertices and 4 faces */ 1044 for (c = cStart; c < cMax; ++c) { 1045 for (r = 0; r < 6; ++r) { 1046 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1047 1048 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1049 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1050 } 1051 } 1052 /* Hybrid edges have 2 vertices and the same faces */ 1053 for (e = eMax; e < eEnd; ++e) { 1054 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1055 PetscInt size; 1056 1057 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1058 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1059 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1060 } 1061 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1062 for (f = fMax; f < fEnd; ++f) { 1063 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1064 PetscInt size; 1065 1066 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1067 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1068 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1069 } 1070 /* Hybrid cell edges have 2 vertices and 4 faces */ 1071 for (c = cMax; c < cEnd; ++c) { 1072 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1073 1074 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1075 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1076 } 1077 /* Interior vertices have identical supports */ 1078 for (v = vStart; v < vEnd; ++v) { 1079 const PetscInt newp = vStartNew + (v - vStart); 1080 PetscInt size; 1081 1082 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1083 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1084 } 1085 /* Interior edge vertices have 2 + faces supports */ 1086 for (e = eStart; e < eMax; ++e) { 1087 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1088 PetscInt size; 1089 1090 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1091 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1092 } 1093 /* Interior face vertices have 4 + cells supports */ 1094 for (f = fStart; f < fMax; ++f) { 1095 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1096 PetscInt size; 1097 1098 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1099 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1100 } 1101 /* Interior cell vertices have 6 supports */ 1102 for (c = cStart; c < cMax; ++c) { 1103 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1104 1105 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1106 } 1107 break; 1108 default: 1109 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1110 } 1111 PetscFunctionReturn(0); 1112 } 1113 1114 #undef __FUNCT__ 1115 #define __FUNCT__ "CellRefinerSetCones" 1116 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1117 { 1118 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1119 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1120 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1121 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 1122 PetscErrorCode ierr; 1123 1124 PetscFunctionBegin; 1125 if (!refiner) PetscFunctionReturn(0); 1126 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1127 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1128 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1129 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1130 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1131 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1132 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1133 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1134 switch (refiner) { 1135 case 1: 1136 /* Simplicial 2D */ 1137 /* 1138 2 1139 |\ 1140 | \ 1141 | \ 1142 | \ 1143 | C \ 1144 | \ 1145 | \ 1146 2---1---1 1147 |\ D / \ 1148 | 2 0 \ 1149 |A \ / B \ 1150 0---0-------1 1151 */ 1152 /* All cells have 3 faces */ 1153 for (c = cStart; c < cEnd; ++c) { 1154 const PetscInt newp = cStartNew + (c - cStart)*4; 1155 const PetscInt *cone, *ornt; 1156 PetscInt coneNew[3], orntNew[3]; 1157 1158 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1159 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1160 /* A triangle */ 1161 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1162 orntNew[0] = ornt[0]; 1163 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1164 orntNew[1] = -2; 1165 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1166 orntNew[2] = ornt[2]; 1167 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1168 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1169 #if 1 1170 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); 1171 for (p = 0; p < 3; ++p) { 1172 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); 1173 } 1174 #endif 1175 /* B triangle */ 1176 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1177 orntNew[0] = ornt[0]; 1178 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1179 orntNew[1] = ornt[1]; 1180 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1181 orntNew[2] = -2; 1182 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1183 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1184 #if 1 1185 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); 1186 for (p = 0; p < 3; ++p) { 1187 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); 1188 } 1189 #endif 1190 /* C triangle */ 1191 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1192 orntNew[0] = -2; 1193 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1194 orntNew[1] = ornt[1]; 1195 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1196 orntNew[2] = ornt[2]; 1197 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1198 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1199 #if 1 1200 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); 1201 for (p = 0; p < 3; ++p) { 1202 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); 1203 } 1204 #endif 1205 /* D triangle */ 1206 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1207 orntNew[0] = 0; 1208 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1209 orntNew[1] = 0; 1210 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1211 orntNew[2] = 0; 1212 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1213 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1214 #if 1 1215 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); 1216 for (p = 0; p < 3; ++p) { 1217 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); 1218 } 1219 #endif 1220 } 1221 /* Split faces have 2 vertices and the same cells as the parent */ 1222 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1223 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1224 for (f = fStart; f < fEnd; ++f) { 1225 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1226 1227 for (r = 0; r < 2; ++r) { 1228 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1229 const PetscInt *cone, *ornt, *support; 1230 PetscInt coneNew[2], coneSize, c, supportSize, s; 1231 1232 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1233 coneNew[0] = vStartNew + (cone[0] - vStart); 1234 coneNew[1] = vStartNew + (cone[1] - vStart); 1235 coneNew[(r+1)%2] = newv; 1236 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1237 #if 1 1238 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1239 for (p = 0; p < 2; ++p) { 1240 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); 1241 } 1242 #endif 1243 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1244 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1245 for (s = 0; s < supportSize; ++s) { 1246 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1247 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1248 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1249 for (c = 0; c < coneSize; ++c) { 1250 if (cone[c] == f) break; 1251 } 1252 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1253 } 1254 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1255 #if 1 1256 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1257 for (p = 0; p < supportSize; ++p) { 1258 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); 1259 } 1260 #endif 1261 } 1262 } 1263 /* Interior faces have 2 vertices and 2 cells */ 1264 for (c = cStart; c < cEnd; ++c) { 1265 const PetscInt *cone; 1266 1267 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1268 for (r = 0; r < 3; ++r) { 1269 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1270 PetscInt coneNew[2]; 1271 PetscInt supportNew[2]; 1272 1273 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1274 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1275 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1276 #if 1 1277 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1278 for (p = 0; p < 2; ++p) { 1279 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); 1280 } 1281 #endif 1282 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1283 supportNew[1] = (c - cStart)*4 + 3; 1284 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1285 #if 1 1286 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1287 for (p = 0; p < 2; ++p) { 1288 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); 1289 } 1290 #endif 1291 } 1292 } 1293 /* Old vertices have identical supports */ 1294 for (v = vStart; v < vEnd; ++v) { 1295 const PetscInt newp = vStartNew + (v - vStart); 1296 const PetscInt *support, *cone; 1297 PetscInt size, s; 1298 1299 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1300 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1301 for (s = 0; s < size; ++s) { 1302 PetscInt r = 0; 1303 1304 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1305 if (cone[1] == v) r = 1; 1306 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1307 } 1308 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1309 #if 1 1310 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1311 for (p = 0; p < size; ++p) { 1312 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); 1313 } 1314 #endif 1315 } 1316 /* Face vertices have 2 + cells*2 supports */ 1317 for (f = fStart; f < fEnd; ++f) { 1318 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1319 const PetscInt *cone, *support; 1320 PetscInt size, s; 1321 1322 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1323 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1324 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1325 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1326 for (s = 0; s < size; ++s) { 1327 PetscInt r = 0; 1328 1329 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1330 if (cone[1] == f) r = 1; 1331 else if (cone[2] == f) r = 2; 1332 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1333 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1334 } 1335 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1336 #if 1 1337 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1338 for (p = 0; p < 2+size*2; ++p) { 1339 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); 1340 } 1341 #endif 1342 } 1343 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1344 break; 1345 case 2: 1346 /* Hex 2D */ 1347 /* 1348 3---------2---------2 1349 | | | 1350 | D 2 C | 1351 | | | 1352 3----3----0----1----1 1353 | | | 1354 | A 0 B | 1355 | | | 1356 0---------0---------1 1357 */ 1358 /* All cells have 4 faces */ 1359 for (c = cStart; c < cEnd; ++c) { 1360 const PetscInt newp = (c - cStart)*4; 1361 const PetscInt *cone, *ornt; 1362 PetscInt coneNew[4], orntNew[4]; 1363 1364 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1365 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1366 /* A quad */ 1367 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1368 orntNew[0] = ornt[0]; 1369 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1370 orntNew[1] = 0; 1371 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1372 orntNew[2] = -2; 1373 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1374 orntNew[3] = ornt[3]; 1375 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1376 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1377 #if 1 1378 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); 1379 for (p = 0; p < 4; ++p) { 1380 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); 1381 } 1382 #endif 1383 /* B quad */ 1384 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1385 orntNew[0] = ornt[0]; 1386 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1387 orntNew[1] = ornt[1]; 1388 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1389 orntNew[2] = 0; 1390 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1391 orntNew[3] = -2; 1392 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1393 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1394 #if 1 1395 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); 1396 for (p = 0; p < 4; ++p) { 1397 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); 1398 } 1399 #endif 1400 /* C quad */ 1401 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1402 orntNew[0] = -2; 1403 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1404 orntNew[1] = ornt[1]; 1405 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1406 orntNew[2] = ornt[2]; 1407 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1408 orntNew[3] = 0; 1409 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1410 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1411 #if 1 1412 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); 1413 for (p = 0; p < 4; ++p) { 1414 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); 1415 } 1416 #endif 1417 /* D quad */ 1418 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1419 orntNew[0] = 0; 1420 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1421 orntNew[1] = -2; 1422 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1423 orntNew[2] = ornt[2]; 1424 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1425 orntNew[3] = ornt[3]; 1426 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1427 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1428 #if 1 1429 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); 1430 for (p = 0; p < 4; ++p) { 1431 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); 1432 } 1433 #endif 1434 } 1435 /* Split faces have 2 vertices and the same cells as the parent */ 1436 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1437 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1438 for (f = fStart; f < fEnd; ++f) { 1439 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1440 1441 for (r = 0; r < 2; ++r) { 1442 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1443 const PetscInt *cone, *ornt, *support; 1444 PetscInt coneNew[2], coneSize, c, supportSize, s; 1445 1446 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1447 coneNew[0] = vStartNew + (cone[0] - vStart); 1448 coneNew[1] = vStartNew + (cone[1] - vStart); 1449 coneNew[(r+1)%2] = newv; 1450 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1451 #if 1 1452 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1453 for (p = 0; p < 2; ++p) { 1454 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); 1455 } 1456 #endif 1457 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1458 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1459 for (s = 0; s < supportSize; ++s) { 1460 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1461 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1462 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1463 for (c = 0; c < coneSize; ++c) { 1464 if (cone[c] == f) break; 1465 } 1466 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1467 } 1468 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1469 #if 1 1470 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1471 for (p = 0; p < supportSize; ++p) { 1472 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); 1473 } 1474 #endif 1475 } 1476 } 1477 /* Interior faces have 2 vertices and 2 cells */ 1478 for (c = cStart; c < cEnd; ++c) { 1479 const PetscInt *cone; 1480 PetscInt coneNew[2], supportNew[2]; 1481 1482 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1483 for (r = 0; r < 4; ++r) { 1484 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1485 1486 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1487 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1488 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1489 #if 1 1490 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1491 for (p = 0; p < 2; ++p) { 1492 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); 1493 } 1494 #endif 1495 supportNew[0] = (c - cStart)*4 + r; 1496 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1497 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1498 #if 1 1499 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1500 for (p = 0; p < 2; ++p) { 1501 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); 1502 } 1503 #endif 1504 } 1505 } 1506 /* Old vertices have identical supports */ 1507 for (v = vStart; v < vEnd; ++v) { 1508 const PetscInt newp = vStartNew + (v - vStart); 1509 const PetscInt *support, *cone; 1510 PetscInt size, s; 1511 1512 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1513 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1514 for (s = 0; s < size; ++s) { 1515 PetscInt r = 0; 1516 1517 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1518 if (cone[1] == v) r = 1; 1519 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1520 } 1521 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1522 #if 1 1523 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1524 for (p = 0; p < size; ++p) { 1525 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); 1526 } 1527 #endif 1528 } 1529 /* Face vertices have 2 + cells supports */ 1530 for (f = fStart; f < fEnd; ++f) { 1531 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1532 const PetscInt *cone, *support; 1533 PetscInt size, s; 1534 1535 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1536 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1537 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1538 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1539 for (s = 0; s < size; ++s) { 1540 PetscInt r = 0; 1541 1542 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1543 if (cone[1] == f) r = 1; 1544 else if (cone[2] == f) r = 2; 1545 else if (cone[3] == f) r = 3; 1546 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1547 } 1548 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1549 #if 1 1550 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1551 for (p = 0; p < 2+size; ++p) { 1552 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); 1553 } 1554 #endif 1555 } 1556 /* Cell vertices have 4 supports */ 1557 for (c = cStart; c < cEnd; ++c) { 1558 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1559 PetscInt supportNew[4]; 1560 1561 for (r = 0; r < 4; ++r) { 1562 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1563 } 1564 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1565 } 1566 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1567 break; 1568 case 3: 1569 /* Hybrid Simplicial 2D */ 1570 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1571 cMax = PetscMin(cEnd, cMax); 1572 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1573 fMax = PetscMin(fEnd, fMax); 1574 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1575 /* Interior cells have 3 faces */ 1576 for (c = cStart; c < cMax; ++c) { 1577 const PetscInt newp = cStartNew + (c - cStart)*4; 1578 const PetscInt *cone, *ornt; 1579 PetscInt coneNew[3], orntNew[3]; 1580 1581 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1582 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1583 /* A triangle */ 1584 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1585 orntNew[0] = ornt[0]; 1586 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1587 orntNew[1] = -2; 1588 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1589 orntNew[2] = ornt[2]; 1590 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1591 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1592 #if 1 1593 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew); 1594 for (p = 0; p < 3; ++p) { 1595 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1596 } 1597 #endif 1598 /* B triangle */ 1599 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1600 orntNew[0] = ornt[0]; 1601 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1602 orntNew[1] = ornt[1]; 1603 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1604 orntNew[2] = -2; 1605 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1606 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1607 #if 1 1608 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew); 1609 for (p = 0; p < 3; ++p) { 1610 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1611 } 1612 #endif 1613 /* C triangle */ 1614 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1615 orntNew[0] = -2; 1616 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1617 orntNew[1] = ornt[1]; 1618 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1619 orntNew[2] = ornt[2]; 1620 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1621 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1622 #if 1 1623 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew); 1624 for (p = 0; p < 3; ++p) { 1625 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1626 } 1627 #endif 1628 /* D triangle */ 1629 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1630 orntNew[0] = 0; 1631 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1632 orntNew[1] = 0; 1633 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1634 orntNew[2] = 0; 1635 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1636 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1637 #if 1 1638 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew); 1639 for (p = 0; p < 3; ++p) { 1640 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1641 } 1642 #endif 1643 } 1644 /* 1645 2----3----3 1646 | | 1647 | B | 1648 | | 1649 0----4--- 1 1650 | | 1651 | A | 1652 | | 1653 0----2----1 1654 */ 1655 /* Hybrid cells have 4 faces */ 1656 for (c = cMax; c < cEnd; ++c) { 1657 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1658 const PetscInt *cone, *ornt; 1659 PetscInt coneNew[4], orntNew[4], r; 1660 1661 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1662 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1663 r = (ornt[0] < 0 ? 1 : 0); 1664 /* A quad */ 1665 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 1666 orntNew[0] = ornt[0]; 1667 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 1668 orntNew[1] = ornt[1]; 1669 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 1670 orntNew[2+r] = 0; 1671 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1672 orntNew[3-r] = 0; 1673 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1674 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1675 #if 1 1676 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); 1677 for (p = 0; p < 4; ++p) { 1678 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); 1679 } 1680 #endif 1681 /* B quad */ 1682 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 1683 orntNew[0] = ornt[0]; 1684 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 1685 orntNew[1] = ornt[1]; 1686 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1687 orntNew[2+r] = 0; 1688 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 1689 orntNew[3-r] = 0; 1690 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1691 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1692 #if 1 1693 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); 1694 for (p = 0; p < 4; ++p) { 1695 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); 1696 } 1697 #endif 1698 } 1699 /* Interior split faces have 2 vertices and the same cells as the parent */ 1700 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1701 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1702 for (f = fStart; f < fMax; ++f) { 1703 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1704 1705 for (r = 0; r < 2; ++r) { 1706 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1707 const PetscInt *cone, *ornt, *support; 1708 PetscInt coneNew[2], coneSize, c, supportSize, s; 1709 1710 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1711 coneNew[0] = vStartNew + (cone[0] - vStart); 1712 coneNew[1] = vStartNew + (cone[1] - vStart); 1713 coneNew[(r+1)%2] = newv; 1714 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1715 #if 1 1716 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1717 for (p = 0; p < 2; ++p) { 1718 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); 1719 } 1720 #endif 1721 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1722 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1723 for (s = 0; s < supportSize; ++s) { 1724 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1725 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1726 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1727 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 1728 if (support[s] >= cMax) { 1729 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 1730 } else { 1731 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1732 } 1733 } 1734 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1735 #if 1 1736 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1737 for (p = 0; p < supportSize; ++p) { 1738 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); 1739 } 1740 #endif 1741 } 1742 } 1743 /* Interior cell faces have 2 vertices and 2 cells */ 1744 for (c = cStart; c < cMax; ++c) { 1745 const PetscInt *cone; 1746 1747 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1748 for (r = 0; r < 3; ++r) { 1749 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1750 PetscInt coneNew[2]; 1751 PetscInt supportNew[2]; 1752 1753 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1754 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1755 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1756 #if 1 1757 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1758 for (p = 0; p < 2; ++p) { 1759 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); 1760 } 1761 #endif 1762 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1763 supportNew[1] = (c - cStart)*4 + 3; 1764 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1765 #if 1 1766 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1767 for (p = 0; p < 2; ++p) { 1768 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); 1769 } 1770 #endif 1771 } 1772 } 1773 /* Interior hybrid faces have 2 vertices and the same cells */ 1774 for (f = fMax; f < fEnd; ++f) { 1775 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1776 const PetscInt *cone, *ornt; 1777 const PetscInt *support; 1778 PetscInt coneNew[2]; 1779 PetscInt supportNew[2]; 1780 PetscInt size, s, r; 1781 1782 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1783 coneNew[0] = vStartNew + (cone[0] - vStart); 1784 coneNew[1] = vStartNew + (cone[1] - vStart); 1785 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1786 #if 1 1787 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1788 for (p = 0; p < 2; ++p) { 1789 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); 1790 } 1791 #endif 1792 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1793 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1794 for (s = 0; s < size; ++s) { 1795 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1796 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1797 for (r = 0; r < 2; ++r) { 1798 if (cone[r+2] == f) break; 1799 } 1800 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 1801 } 1802 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1803 #if 1 1804 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1805 for (p = 0; p < size; ++p) { 1806 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); 1807 } 1808 #endif 1809 } 1810 /* Cell hybrid faces have 2 vertices and 2 cells */ 1811 for (c = cMax; c < cEnd; ++c) { 1812 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1813 const PetscInt *cone; 1814 PetscInt coneNew[2]; 1815 PetscInt supportNew[2]; 1816 1817 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1818 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1819 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1820 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1821 #if 1 1822 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1823 for (p = 0; p < 2; ++p) { 1824 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); 1825 } 1826 #endif 1827 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1828 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1829 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1830 #if 1 1831 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1832 for (p = 0; p < 2; ++p) { 1833 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); 1834 } 1835 #endif 1836 } 1837 /* Old vertices have identical supports */ 1838 for (v = vStart; v < vEnd; ++v) { 1839 const PetscInt newp = vStartNew + (v - vStart); 1840 const PetscInt *support, *cone; 1841 PetscInt size, s; 1842 1843 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1844 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1845 for (s = 0; s < size; ++s) { 1846 if (support[s] >= fMax) { 1847 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1848 } else { 1849 PetscInt r = 0; 1850 1851 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1852 if (cone[1] == v) r = 1; 1853 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1854 } 1855 } 1856 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1857 #if 1 1858 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1859 for (p = 0; p < size; ++p) { 1860 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); 1861 } 1862 #endif 1863 } 1864 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1865 for (f = fStart; f < fMax; ++f) { 1866 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1867 const PetscInt *cone, *support; 1868 PetscInt size, newSize = 2, s; 1869 1870 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1871 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1872 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1873 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1874 for (s = 0; s < size; ++s) { 1875 PetscInt r = 0; 1876 1877 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1878 if (support[s] >= cMax) { 1879 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1880 1881 newSize += 1; 1882 } else { 1883 if (cone[1] == f) r = 1; 1884 else if (cone[2] == f) r = 2; 1885 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1886 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1887 1888 newSize += 2; 1889 } 1890 } 1891 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1892 #if 1 1893 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1894 for (p = 0; p < newSize; ++p) { 1895 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); 1896 } 1897 #endif 1898 } 1899 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1900 break; 1901 case 4: 1902 /* Hybrid Hex 2D */ 1903 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1904 cMax = PetscMin(cEnd, cMax); 1905 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1906 fMax = PetscMin(fEnd, fMax); 1907 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1908 /* Interior cells have 4 faces */ 1909 for (c = cStart; c < cMax; ++c) { 1910 const PetscInt newp = cStartNew + (c - cStart)*4; 1911 const PetscInt *cone, *ornt; 1912 PetscInt coneNew[4], orntNew[4]; 1913 1914 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1915 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1916 /* A quad */ 1917 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1918 orntNew[0] = ornt[0]; 1919 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1920 orntNew[1] = 0; 1921 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1922 orntNew[2] = -2; 1923 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1924 orntNew[3] = ornt[3]; 1925 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1926 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1927 #if 1 1928 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew); 1929 for (p = 0; p < 4; ++p) { 1930 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1931 } 1932 #endif 1933 /* B quad */ 1934 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1935 orntNew[0] = ornt[0]; 1936 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1937 orntNew[1] = ornt[1]; 1938 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1939 orntNew[2] = 0; 1940 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1941 orntNew[3] = -2; 1942 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1943 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1944 #if 1 1945 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew); 1946 for (p = 0; p < 4; ++p) { 1947 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1948 } 1949 #endif 1950 /* C quad */ 1951 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1952 orntNew[0] = -2; 1953 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1954 orntNew[1] = ornt[1]; 1955 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1956 orntNew[2] = ornt[2]; 1957 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1958 orntNew[3] = 0; 1959 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1960 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1961 #if 1 1962 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew); 1963 for (p = 0; p < 4; ++p) { 1964 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1965 } 1966 #endif 1967 /* D quad */ 1968 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1969 orntNew[0] = 0; 1970 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1971 orntNew[1] = -2; 1972 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1973 orntNew[2] = ornt[2]; 1974 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1975 orntNew[3] = ornt[3]; 1976 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1977 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1978 #if 1 1979 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew); 1980 for (p = 0; p < 4; ++p) { 1981 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 1982 } 1983 #endif 1984 } 1985 /* 1986 2----3----3 1987 | | 1988 | B | 1989 | | 1990 0----4--- 1 1991 | | 1992 | A | 1993 | | 1994 0----2----1 1995 */ 1996 /* Hybrid cells have 4 faces */ 1997 for (c = cMax; c < cEnd; ++c) { 1998 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1999 const PetscInt *cone, *ornt; 2000 PetscInt coneNew[4], orntNew[4]; 2001 2002 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2003 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2004 /* A quad */ 2005 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2006 orntNew[0] = ornt[0]; 2007 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2008 orntNew[1] = ornt[1]; 2009 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 2010 orntNew[2] = 0; 2011 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2012 orntNew[3] = 0; 2013 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2014 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2015 #if 1 2016 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); 2017 for (p = 0; p < 4; ++p) { 2018 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); 2019 } 2020 #endif 2021 /* B quad */ 2022 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2023 orntNew[0] = ornt[0]; 2024 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2025 orntNew[1] = ornt[1]; 2026 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2027 orntNew[2] = 0; 2028 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 2029 orntNew[3] = 0; 2030 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2031 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2032 #if 1 2033 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); 2034 for (p = 0; p < 4; ++p) { 2035 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); 2036 } 2037 #endif 2038 } 2039 /* Interior split faces have 2 vertices and the same cells as the parent */ 2040 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2041 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2042 for (f = fStart; f < fMax; ++f) { 2043 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2044 2045 for (r = 0; r < 2; ++r) { 2046 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2047 const PetscInt *cone, *ornt, *support; 2048 PetscInt coneNew[2], coneSize, c, supportSize, s; 2049 2050 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2051 coneNew[0] = vStartNew + (cone[0] - vStart); 2052 coneNew[1] = vStartNew + (cone[1] - vStart); 2053 coneNew[(r+1)%2] = newv; 2054 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2055 #if 1 2056 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2057 for (p = 0; p < 2; ++p) { 2058 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); 2059 } 2060 #endif 2061 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2062 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2063 for (s = 0; s < supportSize; ++s) { 2064 if (support[s] >= cMax) { 2065 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2066 } else { 2067 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2068 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2069 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2070 for (c = 0; c < coneSize; ++c) { 2071 if (cone[c] == f) break; 2072 } 2073 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2074 } 2075 } 2076 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2077 #if 1 2078 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2079 for (p = 0; p < supportSize; ++p) { 2080 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); 2081 } 2082 #endif 2083 } 2084 } 2085 /* Interior cell faces have 2 vertices and 2 cells */ 2086 for (c = cStart; c < cMax; ++c) { 2087 const PetscInt *cone; 2088 2089 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2090 for (r = 0; r < 4; ++r) { 2091 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2092 PetscInt coneNew[2], supportNew[2]; 2093 2094 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2095 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2096 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2097 #if 1 2098 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2099 for (p = 0; p < 2; ++p) { 2100 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); 2101 } 2102 #endif 2103 supportNew[0] = (c - cStart)*4 + r; 2104 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2105 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2106 #if 1 2107 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2108 for (p = 0; p < 2; ++p) { 2109 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); 2110 } 2111 #endif 2112 } 2113 } 2114 /* Hybrid faces have 2 vertices and the same cells */ 2115 for (f = fMax; f < fEnd; ++f) { 2116 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 2117 const PetscInt *cone, *support; 2118 PetscInt coneNew[2], supportNew[2]; 2119 PetscInt size, s, r; 2120 2121 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2122 coneNew[0] = vStartNew + (cone[0] - vStart); 2123 coneNew[1] = vStartNew + (cone[1] - vStart); 2124 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2125 #if 1 2126 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2127 for (p = 0; p < 2; ++p) { 2128 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); 2129 } 2130 #endif 2131 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2132 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2133 for (s = 0; s < size; ++s) { 2134 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2135 for (r = 0; r < 2; ++r) { 2136 if (cone[r+2] == f) break; 2137 } 2138 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2139 } 2140 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2141 #if 1 2142 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2143 for (p = 0; p < size; ++p) { 2144 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); 2145 } 2146 #endif 2147 } 2148 /* Cell hybrid faces have 2 vertices and 2 cells */ 2149 for (c = cMax; c < cEnd; ++c) { 2150 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2151 const PetscInt *cone; 2152 PetscInt coneNew[2], supportNew[2]; 2153 2154 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2155 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2156 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2157 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2158 #if 1 2159 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2160 for (p = 0; p < 2; ++p) { 2161 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); 2162 } 2163 #endif 2164 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2165 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2166 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2167 #if 1 2168 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2169 for (p = 0; p < 2; ++p) { 2170 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); 2171 } 2172 #endif 2173 } 2174 /* Old vertices have identical supports */ 2175 for (v = vStart; v < vEnd; ++v) { 2176 const PetscInt newp = vStartNew + (v - vStart); 2177 const PetscInt *support, *cone; 2178 PetscInt size, s; 2179 2180 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2181 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2182 for (s = 0; s < size; ++s) { 2183 if (support[s] >= fMax) { 2184 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2185 } else { 2186 PetscInt r = 0; 2187 2188 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2189 if (cone[1] == v) r = 1; 2190 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2191 } 2192 } 2193 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2194 #if 1 2195 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2196 for (p = 0; p < size; ++p) { 2197 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); 2198 } 2199 #endif 2200 } 2201 /* Face vertices have 2 + cells supports */ 2202 for (f = fStart; f < fMax; ++f) { 2203 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2204 const PetscInt *cone, *support; 2205 PetscInt size, s; 2206 2207 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2208 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2209 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2210 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2211 for (s = 0; s < size; ++s) { 2212 PetscInt r = 0; 2213 2214 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2215 if (support[s] >= cMax) { 2216 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2217 } else { 2218 if (cone[1] == f) r = 1; 2219 else if (cone[2] == f) r = 2; 2220 else if (cone[3] == f) r = 3; 2221 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2222 } 2223 } 2224 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2225 #if 1 2226 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2227 for (p = 0; p < 2+size; ++p) { 2228 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); 2229 } 2230 #endif 2231 } 2232 /* Cell vertices have 4 supports */ 2233 for (c = cStart; c < cMax; ++c) { 2234 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2235 PetscInt supportNew[4]; 2236 2237 for (r = 0; r < 4; ++r) { 2238 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2239 } 2240 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2241 } 2242 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2243 break; 2244 case 5: 2245 /* Simplicial 3D */ 2246 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2247 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2248 for (c = cStart; c < cEnd; ++c) { 2249 const PetscInt newp = cStartNew + (c - cStart)*8; 2250 const PetscInt *cone, *ornt; 2251 PetscInt coneNew[4], orntNew[4]; 2252 2253 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2254 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2255 /* A tetrahedron: {0, a, c, d} */ 2256 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2257 orntNew[0] = ornt[0]; 2258 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2259 orntNew[1] = ornt[1]; 2260 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2261 orntNew[2] = ornt[2]; 2262 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2263 orntNew[3] = 0; 2264 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2265 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2266 #if 1 2267 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); 2268 for (p = 0; p < 4; ++p) { 2269 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); 2270 } 2271 #endif 2272 /* B tetrahedron: {a, 1, b, e} */ 2273 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2274 orntNew[0] = ornt[0]; 2275 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2276 orntNew[1] = ornt[1]; 2277 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2278 orntNew[2] = 0; 2279 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2280 orntNew[3] = ornt[3]; 2281 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2282 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2283 #if 1 2284 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); 2285 for (p = 0; p < 4; ++p) { 2286 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); 2287 } 2288 #endif 2289 /* C tetrahedron: {c, b, 2, f} */ 2290 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2291 orntNew[0] = ornt[0]; 2292 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2293 orntNew[1] = 0; 2294 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2295 orntNew[2] = ornt[2]; 2296 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2297 orntNew[3] = ornt[3]; 2298 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2299 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2300 #if 1 2301 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); 2302 for (p = 0; p < 4; ++p) { 2303 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); 2304 } 2305 #endif 2306 /* D tetrahedron: {d, e, f, 3} */ 2307 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2308 orntNew[0] = 0; 2309 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2310 orntNew[1] = ornt[1]; 2311 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2312 orntNew[2] = ornt[2]; 2313 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2314 orntNew[3] = ornt[3]; 2315 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2316 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2317 #if 1 2318 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); 2319 for (p = 0; p < 4; ++p) { 2320 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); 2321 } 2322 #endif 2323 /* A' tetrahedron: {d, a, c, f} */ 2324 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2325 orntNew[0] = -3; 2326 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2327 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2328 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2329 orntNew[2] = 0; 2330 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2331 orntNew[3] = 2; 2332 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2333 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2334 #if 1 2335 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); 2336 for (p = 0; p < 4; ++p) { 2337 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); 2338 } 2339 #endif 2340 /* B' tetrahedron: {e, b, a, f} */ 2341 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2342 orntNew[0] = -3; 2343 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2344 orntNew[1] = 1; 2345 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2346 orntNew[2] = 0; 2347 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2348 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2349 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2350 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2351 #if 1 2352 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); 2353 for (p = 0; p < 4; ++p) { 2354 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); 2355 } 2356 #endif 2357 /* C' tetrahedron: {b, f, c, a} */ 2358 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2359 orntNew[0] = -3; 2360 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2361 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2362 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2363 orntNew[2] = -3; 2364 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2365 orntNew[3] = -2; 2366 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2367 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2368 #if 1 2369 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); 2370 for (p = 0; p < 4; ++p) { 2371 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); 2372 } 2373 #endif 2374 /* D' tetrahedron: {f, e, d, a} */ 2375 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2376 orntNew[0] = -3; 2377 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2378 orntNew[1] = -3; 2379 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2380 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2381 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2382 orntNew[3] = -3; 2383 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2384 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2385 #if 1 2386 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); 2387 for (p = 0; p < 4; ++p) { 2388 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); 2389 } 2390 #endif 2391 } 2392 /* Split faces have 3 edges and the same cells as the parent */ 2393 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2394 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2395 for (f = fStart; f < fEnd; ++f) { 2396 const PetscInt newp = fStartNew + (f - fStart)*4; 2397 const PetscInt *cone, *ornt, *support; 2398 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2399 2400 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2401 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2402 /* A triangle */ 2403 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2404 orntNew[0] = ornt[0]; 2405 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2406 orntNew[1] = -2; 2407 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2408 orntNew[2] = ornt[2]; 2409 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2410 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2411 #if 1 2412 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); 2413 for (p = 0; p < 3; ++p) { 2414 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); 2415 } 2416 #endif 2417 /* B triangle */ 2418 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2419 orntNew[0] = ornt[0]; 2420 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2421 orntNew[1] = ornt[1]; 2422 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2423 orntNew[2] = -2; 2424 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2425 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2426 #if 1 2427 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); 2428 for (p = 0; p < 3; ++p) { 2429 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); 2430 } 2431 #endif 2432 /* C triangle */ 2433 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2434 orntNew[0] = -2; 2435 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2436 orntNew[1] = ornt[1]; 2437 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2438 orntNew[2] = ornt[2]; 2439 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2440 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2441 #if 1 2442 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); 2443 for (p = 0; p < 3; ++p) { 2444 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); 2445 } 2446 #endif 2447 /* D triangle */ 2448 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2449 orntNew[0] = 0; 2450 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2451 orntNew[1] = 0; 2452 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2453 orntNew[2] = 0; 2454 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2455 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2456 #if 1 2457 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); 2458 for (p = 0; p < 3; ++p) { 2459 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); 2460 } 2461 #endif 2462 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2463 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2464 for (r = 0; r < 4; ++r) { 2465 for (s = 0; s < supportSize; ++s) { 2466 PetscInt subf; 2467 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2468 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2469 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2470 for (c = 0; c < coneSize; ++c) { 2471 if (cone[c] == f) break; 2472 } 2473 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2474 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2475 } 2476 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2477 #if 1 2478 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); 2479 for (p = 0; p < supportSize; ++p) { 2480 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); 2481 } 2482 #endif 2483 } 2484 } 2485 /* Interior faces have 3 edges and 2 cells */ 2486 for (c = cStart; c < cEnd; ++c) { 2487 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2488 const PetscInt *cone, *ornt; 2489 PetscInt coneNew[3], orntNew[3]; 2490 PetscInt supportNew[2]; 2491 2492 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2493 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2494 /* Face A: {c, a, d} */ 2495 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2496 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2497 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2498 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2499 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2500 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2501 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2502 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2503 #if 1 2504 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2505 for (p = 0; p < 3; ++p) { 2506 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); 2507 } 2508 #endif 2509 supportNew[0] = (c - cStart)*8 + 0; 2510 supportNew[1] = (c - cStart)*8 + 0+4; 2511 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2512 #if 1 2513 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2514 for (p = 0; p < 2; ++p) { 2515 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); 2516 } 2517 #endif 2518 ++newp; 2519 /* Face B: {a, b, e} */ 2520 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2521 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2522 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2523 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2524 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2525 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2526 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2527 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2528 #if 1 2529 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2530 for (p = 0; p < 3; ++p) { 2531 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); 2532 } 2533 #endif 2534 supportNew[0] = (c - cStart)*8 + 1; 2535 supportNew[1] = (c - cStart)*8 + 1+4; 2536 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2537 #if 1 2538 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2539 for (p = 0; p < 2; ++p) { 2540 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); 2541 } 2542 #endif 2543 ++newp; 2544 /* Face C: {c, f, b} */ 2545 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2546 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2547 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2548 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2549 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2550 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2551 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2552 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2553 #if 1 2554 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2555 for (p = 0; p < 3; ++p) { 2556 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); 2557 } 2558 #endif 2559 supportNew[0] = (c - cStart)*8 + 2; 2560 supportNew[1] = (c - cStart)*8 + 2+4; 2561 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2562 #if 1 2563 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2564 for (p = 0; p < 2; ++p) { 2565 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); 2566 } 2567 #endif 2568 ++newp; 2569 /* Face D: {d, e, f} */ 2570 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2571 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2572 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2573 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2574 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2575 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2576 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2577 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2578 #if 1 2579 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2580 for (p = 0; p < 3; ++p) { 2581 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); 2582 } 2583 #endif 2584 supportNew[0] = (c - cStart)*8 + 3; 2585 supportNew[1] = (c - cStart)*8 + 3+4; 2586 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2587 #if 1 2588 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2589 for (p = 0; p < 2; ++p) { 2590 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); 2591 } 2592 #endif 2593 ++newp; 2594 /* Face E: {d, f, a} */ 2595 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2596 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2597 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2598 orntNew[1] = -2; 2599 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2600 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2601 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2602 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2603 #if 1 2604 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2605 for (p = 0; p < 3; ++p) { 2606 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); 2607 } 2608 #endif 2609 supportNew[0] = (c - cStart)*8 + 0+4; 2610 supportNew[1] = (c - cStart)*8 + 3+4; 2611 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2612 #if 1 2613 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2614 for (p = 0; p < 2; ++p) { 2615 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); 2616 } 2617 #endif 2618 ++newp; 2619 /* Face F: {c, a, f} */ 2620 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2621 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2622 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2623 orntNew[1] = 0; 2624 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2625 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2626 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2627 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2628 #if 1 2629 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2630 for (p = 0; p < 3; ++p) { 2631 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); 2632 } 2633 #endif 2634 supportNew[0] = (c - cStart)*8 + 0+4; 2635 supportNew[1] = (c - cStart)*8 + 2+4; 2636 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2637 #if 1 2638 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2639 for (p = 0; p < 2; ++p) { 2640 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); 2641 } 2642 #endif 2643 ++newp; 2644 /* Face G: {e, a, f} */ 2645 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2646 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2647 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2648 orntNew[1] = 0; 2649 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2650 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2651 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2652 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2653 #if 1 2654 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2655 for (p = 0; p < 3; ++p) { 2656 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); 2657 } 2658 #endif 2659 supportNew[0] = (c - cStart)*8 + 1+4; 2660 supportNew[1] = (c - cStart)*8 + 3+4; 2661 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2662 #if 1 2663 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2664 for (p = 0; p < 2; ++p) { 2665 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); 2666 } 2667 #endif 2668 ++newp; 2669 /* Face H: {a, b, f} */ 2670 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2671 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2672 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2673 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2674 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2675 orntNew[2] = -2; 2676 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2677 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2678 #if 1 2679 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2680 for (p = 0; p < 3; ++p) { 2681 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); 2682 } 2683 #endif 2684 supportNew[0] = (c - cStart)*8 + 1+4; 2685 supportNew[1] = (c - cStart)*8 + 2+4; 2686 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2687 #if 1 2688 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2689 for (p = 0; p < 2; ++p) { 2690 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); 2691 } 2692 #endif 2693 ++newp; 2694 } 2695 /* Split Edges have 2 vertices and the same faces as the parent */ 2696 for (e = eStart; e < eEnd; ++e) { 2697 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2698 2699 for (r = 0; r < 2; ++r) { 2700 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2701 const PetscInt *cone, *ornt, *support; 2702 PetscInt coneNew[2], coneSize, c, supportSize, s; 2703 2704 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2705 coneNew[0] = vStartNew + (cone[0] - vStart); 2706 coneNew[1] = vStartNew + (cone[1] - vStart); 2707 coneNew[(r+1)%2] = newv; 2708 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2709 #if 1 2710 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2711 for (p = 0; p < 2; ++p) { 2712 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); 2713 } 2714 #endif 2715 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2716 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2717 for (s = 0; s < supportSize; ++s) { 2718 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2719 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2720 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2721 for (c = 0; c < coneSize; ++c) { 2722 if (cone[c] == e) break; 2723 } 2724 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2725 } 2726 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2727 #if 1 2728 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2729 for (p = 0; p < supportSize; ++p) { 2730 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); 2731 } 2732 #endif 2733 } 2734 } 2735 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2736 for (f = fStart; f < fEnd; ++f) { 2737 const PetscInt *cone, *ornt, *support; 2738 PetscInt coneSize, supportSize, s; 2739 2740 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2741 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2742 for (r = 0; r < 3; ++r) { 2743 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2744 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2745 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2746 -1, -1, 1, 6, 0, 4, 2747 2, 5, 3, 4, -1, -1, 2748 -1, -1, 3, 6, 2, 7}; 2749 2750 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2751 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2752 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2753 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2754 #if 1 2755 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2756 for (p = 0; p < 2; ++p) { 2757 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2758 } 2759 #endif 2760 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2761 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2762 for (s = 0; s < supportSize; ++s) { 2763 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2764 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2765 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2766 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2767 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2768 er = GetTetSomethingInverse_Static(ornt[c], r); 2769 if (er == eint[c]) { 2770 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2771 } else { 2772 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2773 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2774 } 2775 } 2776 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2777 #if 1 2778 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2779 for (p = 0; p < intFaces; ++p) { 2780 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); 2781 } 2782 #endif 2783 } 2784 } 2785 /* Interior edges have 2 vertices and 4 faces */ 2786 for (c = cStart; c < cEnd; ++c) { 2787 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2788 const PetscInt *cone, *ornt, *fcone; 2789 PetscInt coneNew[2], supportNew[4], find; 2790 2791 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2792 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2793 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2794 find = GetTriEdge_Static(ornt[0], 0); 2795 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2796 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2797 find = GetTriEdge_Static(ornt[2], 1); 2798 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2799 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2800 #if 1 2801 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2802 for (p = 0; p < 2; ++p) { 2803 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); 2804 } 2805 #endif 2806 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2807 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2808 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2809 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2810 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2811 #if 1 2812 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2813 for (p = 0; p < 4; ++p) { 2814 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); 2815 } 2816 #endif 2817 } 2818 /* Old vertices have identical supports */ 2819 for (v = vStart; v < vEnd; ++v) { 2820 const PetscInt newp = vStartNew + (v - vStart); 2821 const PetscInt *support, *cone; 2822 PetscInt size, s; 2823 2824 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2825 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2826 for (s = 0; s < size; ++s) { 2827 PetscInt r = 0; 2828 2829 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2830 if (cone[1] == v) r = 1; 2831 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2832 } 2833 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2834 #if 1 2835 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2836 for (p = 0; p < size; ++p) { 2837 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); 2838 } 2839 #endif 2840 } 2841 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2842 for (e = eStart; e < eEnd; ++e) { 2843 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2844 const PetscInt *cone, *support; 2845 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2846 2847 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2848 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2849 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2850 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2851 for (s = 0; s < size; ++s) { 2852 PetscInt r = 0; 2853 2854 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2855 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2856 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2857 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2858 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2859 } 2860 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2861 for (s = 0; s < starSize*2; s += 2) { 2862 const PetscInt *cone, *ornt; 2863 PetscInt e01, e23; 2864 2865 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2866 /* Check edge 0-1 */ 2867 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2868 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2869 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2870 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2871 /* Check edge 2-3 */ 2872 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2873 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2874 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2875 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2876 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2877 } 2878 } 2879 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2880 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2881 #if 1 2882 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2883 for (p = 0; p < 2+size*2+cellSize; ++p) { 2884 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); 2885 } 2886 #endif 2887 } 2888 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2889 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2890 break; 2891 case 7: 2892 /* Hybrid Simplicial 3D */ 2893 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2894 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2895 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2896 for (c = cStart; c < cMax; ++c) { 2897 const PetscInt newp = cStartNew + (c - cStart)*8; 2898 const PetscInt *cone, *ornt; 2899 PetscInt coneNew[4], orntNew[4]; 2900 2901 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2902 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2903 /* A tetrahedron: {0, a, c, d} */ 2904 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2905 orntNew[0] = ornt[0]; 2906 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2907 orntNew[1] = ornt[1]; 2908 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2909 orntNew[2] = ornt[2]; 2910 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2911 orntNew[3] = 0; 2912 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2913 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2914 #if 1 2915 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); 2916 for (p = 0; p < 4; ++p) { 2917 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); 2918 } 2919 #endif 2920 /* B tetrahedron: {a, 1, b, e} */ 2921 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2922 orntNew[0] = ornt[0]; 2923 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2924 orntNew[1] = ornt[1]; 2925 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2926 orntNew[2] = 0; 2927 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2928 orntNew[3] = ornt[3]; 2929 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2930 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2931 #if 1 2932 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); 2933 for (p = 0; p < 4; ++p) { 2934 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); 2935 } 2936 #endif 2937 /* C tetrahedron: {c, b, 2, f} */ 2938 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2939 orntNew[0] = ornt[0]; 2940 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2941 orntNew[1] = 0; 2942 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2943 orntNew[2] = ornt[2]; 2944 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2945 orntNew[3] = ornt[3]; 2946 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2947 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2948 #if 1 2949 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); 2950 for (p = 0; p < 4; ++p) { 2951 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); 2952 } 2953 #endif 2954 /* D tetrahedron: {d, e, f, 3} */ 2955 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2956 orntNew[0] = 0; 2957 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2958 orntNew[1] = ornt[1]; 2959 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2960 orntNew[2] = ornt[2]; 2961 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2962 orntNew[3] = ornt[3]; 2963 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2964 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2965 #if 1 2966 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); 2967 for (p = 0; p < 4; ++p) { 2968 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); 2969 } 2970 #endif 2971 /* A' tetrahedron: {d, a, c, f} */ 2972 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2973 orntNew[0] = -3; 2974 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2975 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2976 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2977 orntNew[2] = 0; 2978 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2979 orntNew[3] = 2; 2980 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2981 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2982 #if 1 2983 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); 2984 for (p = 0; p < 4; ++p) { 2985 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); 2986 } 2987 #endif 2988 /* B' tetrahedron: {e, b, a, f} */ 2989 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2990 orntNew[0] = -3; 2991 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2992 orntNew[1] = 1; 2993 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2994 orntNew[2] = 0; 2995 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2996 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2997 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2998 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2999 #if 1 3000 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); 3001 for (p = 0; p < 4; ++p) { 3002 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); 3003 } 3004 #endif 3005 /* C' tetrahedron: {b, f, c, a} */ 3006 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3007 orntNew[0] = -3; 3008 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 3009 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 3010 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3011 orntNew[2] = -3; 3012 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3013 orntNew[3] = -2; 3014 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3015 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3016 #if 1 3017 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); 3018 for (p = 0; p < 4; ++p) { 3019 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); 3020 } 3021 #endif 3022 /* D' tetrahedron: {f, e, d, a} */ 3023 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3024 orntNew[0] = -3; 3025 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3026 orntNew[1] = -3; 3027 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 3028 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 3029 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3030 orntNew[3] = -3; 3031 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3032 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3033 #if 1 3034 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); 3035 for (p = 0; p < 4; ++p) { 3036 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); 3037 } 3038 #endif 3039 } 3040 /* Hybrid cells have 5 faces */ 3041 for (c = cMax; c < cEnd; ++c) { 3042 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 3043 const PetscInt *cone, *ornt, *fornt; 3044 PetscInt coneNew[5], orntNew[5], o, of, i; 3045 3046 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3047 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3048 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 3049 o = ornt[0] < 0 ? -1 : 1; 3050 for (r = 0; r < 3; ++r) { 3051 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 3052 orntNew[0] = ornt[0]; 3053 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 3054 orntNew[1] = ornt[1]; 3055 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 3056 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 3057 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 3058 orntNew[i] = 0; 3059 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 3060 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 3061 orntNew[i] = 0; 3062 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 3063 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 3064 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], (r+2)%3)] - fMax)*2 + (o*of < 0 ? 0 : 1); 3065 orntNew[i] = 0; 3066 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3067 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3068 #if 1 3069 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); 3070 for (p = 0; p < 2; ++p) { 3071 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); 3072 } 3073 for (p = 2; p < 5; ++p) { 3074 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); 3075 } 3076 #endif 3077 } 3078 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 3079 orntNew[0] = 0; 3080 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3081 orntNew[1] = 0; 3082 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3083 orntNew[2] = 0; 3084 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3085 orntNew[3] = 0; 3086 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3087 orntNew[4] = 0; 3088 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3089 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3090 #if 1 3091 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); 3092 for (p = 0; p < 2; ++p) { 3093 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); 3094 } 3095 for (p = 2; p < 5; ++p) { 3096 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); 3097 } 3098 #endif 3099 } 3100 /* Split faces have 3 edges and the same cells as the parent */ 3101 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3102 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3103 for (f = fStart; f < fMax; ++f) { 3104 const PetscInt newp = fStartNew + (f - fStart)*4; 3105 const PetscInt *cone, *ornt, *support; 3106 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3107 3108 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3109 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3110 /* A triangle */ 3111 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3112 orntNew[0] = ornt[0]; 3113 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3114 orntNew[1] = -2; 3115 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3116 orntNew[2] = ornt[2]; 3117 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3118 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3119 #if 1 3120 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); 3121 for (p = 0; p < 3; ++p) { 3122 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); 3123 } 3124 #endif 3125 /* B triangle */ 3126 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3127 orntNew[0] = ornt[0]; 3128 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3129 orntNew[1] = ornt[1]; 3130 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3131 orntNew[2] = -2; 3132 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3133 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3134 #if 1 3135 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); 3136 for (p = 0; p < 3; ++p) { 3137 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); 3138 } 3139 #endif 3140 /* C triangle */ 3141 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3142 orntNew[0] = -2; 3143 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3144 orntNew[1] = ornt[1]; 3145 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3146 orntNew[2] = ornt[2]; 3147 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3148 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3149 #if 1 3150 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); 3151 for (p = 0; p < 3; ++p) { 3152 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); 3153 } 3154 #endif 3155 /* D triangle */ 3156 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3157 orntNew[0] = 0; 3158 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3159 orntNew[1] = 0; 3160 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3161 orntNew[2] = 0; 3162 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3163 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3164 #if 1 3165 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); 3166 for (p = 0; p < 3; ++p) { 3167 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); 3168 } 3169 #endif 3170 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3171 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3172 for (r = 0; r < 4; ++r) { 3173 for (s = 0; s < supportSize; ++s) { 3174 PetscInt subf; 3175 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3176 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3177 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3178 for (c = 0; c < coneSize; ++c) { 3179 if (cone[c] == f) break; 3180 } 3181 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3182 if (support[s] < cMax) { 3183 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3184 } else { 3185 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3186 } 3187 } 3188 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3189 #if 1 3190 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); 3191 for (p = 0; p < supportSize; ++p) { 3192 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); 3193 } 3194 #endif 3195 } 3196 } 3197 /* Interior cell faces have 3 edges and 2 cells */ 3198 for (c = cStart; c < cMax; ++c) { 3199 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3200 const PetscInt *cone, *ornt; 3201 PetscInt coneNew[3], orntNew[3]; 3202 PetscInt supportNew[2]; 3203 3204 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3205 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3206 /* Face A: {c, a, d} */ 3207 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3208 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3209 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3210 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3211 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 3212 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3213 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3214 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3215 #if 1 3216 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3217 for (p = 0; p < 3; ++p) { 3218 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); 3219 } 3220 #endif 3221 supportNew[0] = (c - cStart)*8 + 0; 3222 supportNew[1] = (c - cStart)*8 + 0+4; 3223 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3224 #if 1 3225 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3226 for (p = 0; p < 2; ++p) { 3227 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); 3228 } 3229 #endif 3230 ++newp; 3231 /* Face B: {a, b, e} */ 3232 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3233 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3234 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 3235 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3236 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3237 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3238 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3239 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3240 #if 1 3241 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); 3242 for (p = 0; p < 3; ++p) { 3243 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); 3244 } 3245 #endif 3246 supportNew[0] = (c - cStart)*8 + 1; 3247 supportNew[1] = (c - cStart)*8 + 1+4; 3248 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3249 #if 1 3250 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3251 for (p = 0; p < 2; ++p) { 3252 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); 3253 } 3254 #endif 3255 ++newp; 3256 /* Face C: {c, f, b} */ 3257 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3258 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3259 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3260 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3261 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 3262 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3263 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3264 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3265 #if 1 3266 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3267 for (p = 0; p < 3; ++p) { 3268 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); 3269 } 3270 #endif 3271 supportNew[0] = (c - cStart)*8 + 2; 3272 supportNew[1] = (c - cStart)*8 + 2+4; 3273 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3274 #if 1 3275 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3276 for (p = 0; p < 2; ++p) { 3277 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); 3278 } 3279 #endif 3280 ++newp; 3281 /* Face D: {d, e, f} */ 3282 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 3283 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3284 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3285 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3286 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3287 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3288 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3289 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3290 #if 1 3291 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3292 for (p = 0; p < 3; ++p) { 3293 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); 3294 } 3295 #endif 3296 supportNew[0] = (c - cStart)*8 + 3; 3297 supportNew[1] = (c - cStart)*8 + 3+4; 3298 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3299 #if 1 3300 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3301 for (p = 0; p < 2; ++p) { 3302 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); 3303 } 3304 #endif 3305 ++newp; 3306 /* Face E: {d, f, a} */ 3307 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3308 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3309 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3310 orntNew[1] = -2; 3311 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3312 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3313 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3314 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3315 #if 1 3316 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3317 for (p = 0; p < 3; ++p) { 3318 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); 3319 } 3320 #endif 3321 supportNew[0] = (c - cStart)*8 + 0+4; 3322 supportNew[1] = (c - cStart)*8 + 3+4; 3323 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3324 #if 1 3325 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3326 for (p = 0; p < 2; ++p) { 3327 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); 3328 } 3329 #endif 3330 ++newp; 3331 /* Face F: {c, a, f} */ 3332 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3333 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3334 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3335 orntNew[1] = 0; 3336 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3337 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3338 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3339 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3340 #if 1 3341 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3342 for (p = 0; p < 3; ++p) { 3343 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); 3344 } 3345 #endif 3346 supportNew[0] = (c - cStart)*8 + 0+4; 3347 supportNew[1] = (c - cStart)*8 + 2+4; 3348 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3349 #if 1 3350 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3351 for (p = 0; p < 2; ++p) { 3352 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); 3353 } 3354 #endif 3355 ++newp; 3356 /* Face G: {e, a, f} */ 3357 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3358 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3359 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3360 orntNew[1] = 0; 3361 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3362 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3363 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3364 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3365 #if 1 3366 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3367 for (p = 0; p < 3; ++p) { 3368 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); 3369 } 3370 #endif 3371 supportNew[0] = (c - cStart)*8 + 1+4; 3372 supportNew[1] = (c - cStart)*8 + 3+4; 3373 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3374 #if 1 3375 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3376 for (p = 0; p < 2; ++p) { 3377 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); 3378 } 3379 #endif 3380 ++newp; 3381 /* Face H: {a, b, f} */ 3382 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3383 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3384 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3385 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3386 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3387 orntNew[2] = -2; 3388 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3389 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3390 #if 1 3391 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3392 for (p = 0; p < 3; ++p) { 3393 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); 3394 } 3395 #endif 3396 supportNew[0] = (c - cStart)*8 + 1+4; 3397 supportNew[1] = (c - cStart)*8 + 2+4; 3398 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3399 #if 1 3400 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3401 for (p = 0; p < 2; ++p) { 3402 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); 3403 } 3404 #endif 3405 ++newp; 3406 } 3407 /* Hybrid split faces have 4 edges and same cells */ 3408 for (f = fMax; f < fEnd; ++f) { 3409 const PetscInt *cone, *ornt, *support; 3410 PetscInt coneNew[4], orntNew[4]; 3411 PetscInt supportNew[2], size, s, c; 3412 3413 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3414 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3415 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3416 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3417 for (r = 0; r < 2; ++r) { 3418 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3419 3420 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3421 orntNew[0] = ornt[0]; 3422 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3423 orntNew[1] = ornt[1]; 3424 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3425 orntNew[2+r] = 0; 3426 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3427 orntNew[3-r] = 0; 3428 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3429 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3430 #if 1 3431 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3432 for (p = 0; p < 2; ++p) { 3433 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); 3434 } 3435 for (p = 2; p < 4; ++p) { 3436 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); 3437 } 3438 #endif 3439 for (s = 0; s < size; ++s) { 3440 const PetscInt *coneCell, *orntCell, *fornt; 3441 PetscInt o, of; 3442 3443 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3444 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3445 o = orntCell[0] < 0 ? -1 : 1; 3446 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3447 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3448 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3449 of = fornt[c-2] < 0 ? -1 : 1; 3450 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3451 } 3452 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3453 #if 1 3454 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3455 for (p = 0; p < size; ++p) { 3456 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); 3457 } 3458 #endif 3459 } 3460 } 3461 /* Hybrid cell faces have 4 edges and 2 cells */ 3462 for (c = cMax; c < cEnd; ++c) { 3463 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3464 const PetscInt *cone, *ornt; 3465 PetscInt coneNew[4], orntNew[4]; 3466 PetscInt supportNew[2]; 3467 3468 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3469 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3470 for (r = 0; r < 3; ++r) { 3471 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3472 orntNew[0] = 0; 3473 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3474 orntNew[1] = 0; 3475 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3476 orntNew[2] = 0; 3477 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3478 orntNew[3] = 0; 3479 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3480 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3481 #if 1 3482 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); 3483 for (p = 0; p < 2; ++p) { 3484 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); 3485 } 3486 for (p = 2; p < 4; ++p) { 3487 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); 3488 } 3489 #endif 3490 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3491 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3492 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3493 #if 1 3494 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); 3495 for (p = 0; p < 2; ++p) { 3496 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); 3497 } 3498 #endif 3499 } 3500 } 3501 /* Interior split edges have 2 vertices and the same faces as the parent */ 3502 for (e = eStart; e < eMax; ++e) { 3503 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3504 3505 for (r = 0; r < 2; ++r) { 3506 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3507 const PetscInt *cone, *ornt, *support; 3508 PetscInt coneNew[2], coneSize, c, supportSize, s; 3509 3510 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3511 coneNew[0] = vStartNew + (cone[0] - vStart); 3512 coneNew[1] = vStartNew + (cone[1] - vStart); 3513 coneNew[(r+1)%2] = newv; 3514 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3515 #if 1 3516 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3517 for (p = 0; p < 2; ++p) { 3518 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); 3519 } 3520 #endif 3521 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3522 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3523 for (s = 0; s < supportSize; ++s) { 3524 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3525 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3526 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3527 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3528 if (support[s] < fMax) { 3529 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3530 } else { 3531 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3532 } 3533 } 3534 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3535 #if 1 3536 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3537 for (p = 0; p < supportSize; ++p) { 3538 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); 3539 } 3540 #endif 3541 } 3542 } 3543 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3544 for (f = fStart; f < fMax; ++f) { 3545 const PetscInt *cone, *ornt, *support; 3546 PetscInt coneSize, supportSize, s; 3547 3548 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3549 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3550 for (r = 0; r < 3; ++r) { 3551 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3552 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3553 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3554 -1, -1, 1, 6, 0, 4, 3555 2, 5, 3, 4, -1, -1, 3556 -1, -1, 3, 6, 2, 7}; 3557 3558 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3559 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3560 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3561 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3562 #if 1 3563 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3564 for (p = 0; p < 2; ++p) { 3565 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); 3566 } 3567 #endif 3568 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3569 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3570 for (s = 0; s < supportSize; ++s) { 3571 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3572 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3573 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3574 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3575 if (support[s] < cMax) { 3576 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3577 er = GetTetSomethingInverse_Static(ornt[c], r); 3578 if (er == eint[c]) { 3579 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3580 } else { 3581 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3582 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3583 } 3584 } else { 3585 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 3586 } 3587 } 3588 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3589 #if 1 3590 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3591 for (p = 0; p < intFaces; ++p) { 3592 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); 3593 } 3594 #endif 3595 } 3596 } 3597 /* Interior cell edges have 2 vertices and 4 faces */ 3598 for (c = cStart; c < cMax; ++c) { 3599 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3600 const PetscInt *cone, *ornt, *fcone; 3601 PetscInt coneNew[2], supportNew[4], find; 3602 3603 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3604 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3605 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3606 find = GetTriEdge_Static(ornt[0], 0); 3607 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3608 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3609 find = GetTriEdge_Static(ornt[2], 1); 3610 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3611 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3612 #if 1 3613 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3614 for (p = 0; p < 2; ++p) { 3615 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); 3616 } 3617 #endif 3618 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3619 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3620 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3621 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3622 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3623 #if 1 3624 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3625 for (p = 0; p < 4; ++p) { 3626 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); 3627 } 3628 #endif 3629 } 3630 /* Hybrid edges have two vertices and the same faces */ 3631 for (e = eMax; e < eEnd; ++e) { 3632 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3633 const PetscInt *cone, *support, *fcone; 3634 PetscInt coneNew[2], size, fsize, s; 3635 3636 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3637 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3638 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3639 coneNew[0] = vStartNew + (cone[0] - vStart); 3640 coneNew[1] = vStartNew + (cone[1] - vStart); 3641 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3642 #if 1 3643 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3644 for (p = 0; p < 2; ++p) { 3645 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); 3646 } 3647 #endif 3648 for (s = 0; s < size; ++s) { 3649 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3650 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3651 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3652 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3653 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3654 } 3655 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3656 #if 1 3657 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3658 for (p = 0; p < size; ++p) { 3659 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); 3660 } 3661 #endif 3662 } 3663 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3664 for (f = fMax; f < fEnd; ++f) { 3665 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3666 const PetscInt *cone, *support, *ccone, *cornt; 3667 PetscInt coneNew[2], size, csize, s; 3668 3669 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3670 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3671 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3672 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3673 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3674 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3675 #if 1 3676 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3677 for (p = 0; p < 2; ++p) { 3678 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); 3679 } 3680 #endif 3681 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3682 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3683 for (s = 0; s < size; ++s) { 3684 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3685 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3686 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3687 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3688 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]); 3689 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 3690 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 3691 } 3692 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3693 #if 1 3694 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3695 for (p = 0; p < 2+size*2; ++p) { 3696 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); 3697 } 3698 #endif 3699 } 3700 /* Interior vertices have identical supports */ 3701 for (v = vStart; v < vEnd; ++v) { 3702 const PetscInt newp = vStartNew + (v - vStart); 3703 const PetscInt *support, *cone; 3704 PetscInt size, s; 3705 3706 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3707 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3708 for (s = 0; s < size; ++s) { 3709 PetscInt r = 0; 3710 3711 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3712 if (cone[1] == v) r = 1; 3713 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3714 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3715 } 3716 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3717 #if 1 3718 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3719 for (p = 0; p < size; ++p) { 3720 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); 3721 } 3722 #endif 3723 } 3724 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3725 for (e = eStart; e < eMax; ++e) { 3726 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3727 const PetscInt *cone, *support; 3728 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3729 3730 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3731 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3732 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3733 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3734 for (s = 0; s < size; ++s) { 3735 PetscInt r = 0; 3736 3737 if (support[s] < fMax) { 3738 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3739 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3740 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3741 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3742 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3743 faceSize += 2; 3744 } else { 3745 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3746 ++faceSize; 3747 } 3748 } 3749 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3750 for (s = 0; s < starSize*2; s += 2) { 3751 const PetscInt *cone, *ornt; 3752 PetscInt e01, e23; 3753 3754 if ((star[s] >= cStart) && (star[s] < cMax)) { 3755 /* Check edge 0-1 */ 3756 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3757 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3758 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3759 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3760 /* Check edge 2-3 */ 3761 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3762 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3763 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3764 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3765 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3766 } 3767 } 3768 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3769 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3770 #if 1 3771 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3772 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3773 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); 3774 } 3775 #endif 3776 } 3777 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3778 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3779 break; 3780 case 6: 3781 /* Hex 3D */ 3782 /* 3783 Bottom (viewed from top) Top 3784 1---------2---------2 7---------2---------6 3785 | | | | | | 3786 | B 2 C | | H 2 G | 3787 | | | | | | 3788 3----3----0----1----1 3----3----0----1----1 3789 | | | | | | 3790 | A 0 D | | E 0 F | 3791 | | | | | | 3792 0---------0---------3 4---------0---------5 3793 */ 3794 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3795 for (c = cStart; c < cEnd; ++c) { 3796 const PetscInt newp = (c - cStart)*8; 3797 const PetscInt *cone, *ornt; 3798 PetscInt coneNew[6], orntNew[6]; 3799 3800 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3801 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3802 /* A hex */ 3803 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3804 orntNew[0] = ornt[0]; 3805 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3806 orntNew[1] = 0; 3807 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3808 orntNew[2] = ornt[2]; 3809 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3810 orntNew[3] = 0; 3811 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3812 orntNew[4] = 0; 3813 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3814 orntNew[5] = ornt[5]; 3815 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3816 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3817 #if 1 3818 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); 3819 for (p = 0; p < 6; ++p) { 3820 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); 3821 } 3822 #endif 3823 /* B hex */ 3824 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3825 orntNew[0] = ornt[0]; 3826 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3827 orntNew[1] = 0; 3828 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3829 orntNew[2] = -1; 3830 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3831 orntNew[3] = ornt[3]; 3832 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3833 orntNew[4] = 0; 3834 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3835 orntNew[5] = ornt[5]; 3836 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3837 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3838 #if 1 3839 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); 3840 for (p = 0; p < 6; ++p) { 3841 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); 3842 } 3843 #endif 3844 /* C hex */ 3845 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3846 orntNew[0] = ornt[0]; 3847 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3848 orntNew[1] = 0; 3849 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3850 orntNew[2] = -1; 3851 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3852 orntNew[3] = ornt[3]; 3853 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3854 orntNew[4] = ornt[4]; 3855 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3856 orntNew[5] = -4; 3857 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3858 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3859 #if 1 3860 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); 3861 for (p = 0; p < 6; ++p) { 3862 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); 3863 } 3864 #endif 3865 /* D hex */ 3866 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3867 orntNew[0] = ornt[0]; 3868 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3869 orntNew[1] = 0; 3870 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3871 orntNew[2] = ornt[2]; 3872 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3873 orntNew[3] = 0; 3874 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3875 orntNew[4] = ornt[4]; 3876 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3877 orntNew[5] = -4; 3878 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3879 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3880 #if 1 3881 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); 3882 for (p = 0; p < 6; ++p) { 3883 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); 3884 } 3885 #endif 3886 /* E hex */ 3887 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3888 orntNew[0] = -4; 3889 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3890 orntNew[1] = ornt[1]; 3891 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3892 orntNew[2] = ornt[2]; 3893 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3894 orntNew[3] = 0; 3895 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3896 orntNew[4] = -1; 3897 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3898 orntNew[5] = ornt[5]; 3899 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3900 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3901 #if 1 3902 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); 3903 for (p = 0; p < 6; ++p) { 3904 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); 3905 } 3906 #endif 3907 /* F hex */ 3908 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3909 orntNew[0] = -4; 3910 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3911 orntNew[1] = ornt[1]; 3912 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3913 orntNew[2] = ornt[2]; 3914 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3915 orntNew[3] = -1; 3916 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3917 orntNew[4] = ornt[4]; 3918 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3919 orntNew[5] = 1; 3920 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3921 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3922 #if 1 3923 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); 3924 for (p = 0; p < 6; ++p) { 3925 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); 3926 } 3927 #endif 3928 /* G hex */ 3929 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3930 orntNew[0] = -4; 3931 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3932 orntNew[1] = ornt[1]; 3933 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3934 orntNew[2] = 0; 3935 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3936 orntNew[3] = ornt[3]; 3937 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3938 orntNew[4] = ornt[4]; 3939 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3940 orntNew[5] = -3; 3941 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3942 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3943 #if 1 3944 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); 3945 for (p = 0; p < 6; ++p) { 3946 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); 3947 } 3948 #endif 3949 /* H hex */ 3950 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3951 orntNew[0] = -4; 3952 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3953 orntNew[1] = ornt[1]; 3954 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3955 orntNew[2] = -1; 3956 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3957 orntNew[3] = ornt[3]; 3958 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3959 orntNew[4] = 3; 3960 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3961 orntNew[5] = ornt[5]; 3962 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3963 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3964 #if 1 3965 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); 3966 for (p = 0; p < 6; ++p) { 3967 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); 3968 } 3969 #endif 3970 } 3971 /* Split faces have 4 edges and the same cells as the parent */ 3972 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3973 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3974 for (f = fStart; f < fEnd; ++f) { 3975 for (r = 0; r < 4; ++r) { 3976 /* TODO: This can come from GetFaces_Internal() */ 3977 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}; 3978 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3979 const PetscInt *cone, *ornt, *support; 3980 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3981 3982 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3983 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3984 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3985 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3986 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3987 orntNew[(r+0)%4] = ornt[r]; 3988 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3989 orntNew[(r+1)%4] = 0; 3990 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3991 orntNew[(r+2)%4] = -2; 3992 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3993 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3994 #if 1 3995 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3996 for (p = 0; p < 4; ++p) { 3997 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3998 } 3999 #endif 4000 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4001 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4002 for (s = 0; s < supportSize; ++s) { 4003 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4004 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4005 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4006 for (c = 0; c < coneSize; ++c) { 4007 if (cone[c] == f) break; 4008 } 4009 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 4010 } 4011 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4012 #if 1 4013 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4014 for (p = 0; p < supportSize; ++p) { 4015 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); 4016 } 4017 #endif 4018 } 4019 } 4020 /* Interior faces have 4 edges and 2 cells */ 4021 for (c = cStart; c < cEnd; ++c) { 4022 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}; 4023 const PetscInt *cone, *ornt; 4024 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4025 4026 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4027 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4028 /* A-D face */ 4029 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 4030 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4031 orntNew[0] = 0; 4032 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4033 orntNew[1] = 0; 4034 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4035 orntNew[2] = -2; 4036 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4037 orntNew[3] = -2; 4038 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4039 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4040 #if 1 4041 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4042 for (p = 0; p < 4; ++p) { 4043 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); 4044 } 4045 #endif 4046 /* C-D face */ 4047 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 4048 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4049 orntNew[0] = 0; 4050 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4051 orntNew[1] = 0; 4052 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4053 orntNew[2] = -2; 4054 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4055 orntNew[3] = -2; 4056 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4057 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4058 #if 1 4059 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4060 for (p = 0; p < 4; ++p) { 4061 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); 4062 } 4063 #endif 4064 /* B-C face */ 4065 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 4066 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4067 orntNew[0] = -2; 4068 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4069 orntNew[1] = 0; 4070 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4071 orntNew[2] = 0; 4072 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4073 orntNew[3] = -2; 4074 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4075 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4076 #if 1 4077 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4078 for (p = 0; p < 4; ++p) { 4079 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); 4080 } 4081 #endif 4082 /* A-B face */ 4083 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 4084 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4085 orntNew[0] = -2; 4086 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4087 orntNew[1] = 0; 4088 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4089 orntNew[2] = 0; 4090 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4091 orntNew[3] = -2; 4092 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4093 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4094 #if 1 4095 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4096 for (p = 0; p < 4; ++p) { 4097 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); 4098 } 4099 #endif 4100 /* E-F face */ 4101 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 4102 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4103 orntNew[0] = -2; 4104 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4105 orntNew[1] = -2; 4106 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4107 orntNew[2] = 0; 4108 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4109 orntNew[3] = 0; 4110 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4111 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4112 #if 1 4113 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4114 for (p = 0; p < 4; ++p) { 4115 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); 4116 } 4117 #endif 4118 /* F-G face */ 4119 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 4120 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4121 orntNew[0] = -2; 4122 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4123 orntNew[1] = -2; 4124 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4125 orntNew[2] = 0; 4126 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4127 orntNew[3] = 0; 4128 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4129 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4130 #if 1 4131 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4132 for (p = 0; p < 4; ++p) { 4133 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); 4134 } 4135 #endif 4136 /* G-H face */ 4137 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 4138 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4139 orntNew[0] = -2; 4140 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4141 orntNew[1] = 0; 4142 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4143 orntNew[2] = 0; 4144 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4145 orntNew[3] = -2; 4146 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4147 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4148 #if 1 4149 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4150 for (p = 0; p < 4; ++p) { 4151 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); 4152 } 4153 #endif 4154 /* E-H face */ 4155 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 4156 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4157 orntNew[0] = -2; 4158 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4159 orntNew[1] = -2; 4160 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4161 orntNew[2] = 0; 4162 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4163 orntNew[3] = 0; 4164 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4165 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4166 #if 1 4167 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4168 for (p = 0; p < 4; ++p) { 4169 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); 4170 } 4171 #endif 4172 /* A-E face */ 4173 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 4174 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4175 orntNew[0] = 0; 4176 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4177 orntNew[1] = 0; 4178 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4179 orntNew[2] = -2; 4180 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4181 orntNew[3] = -2; 4182 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4183 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4184 #if 1 4185 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4186 for (p = 0; p < 4; ++p) { 4187 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); 4188 } 4189 #endif 4190 /* D-F face */ 4191 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 4192 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4193 orntNew[0] = -2; 4194 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4195 orntNew[1] = 0; 4196 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4197 orntNew[2] = 0; 4198 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4199 orntNew[3] = -2; 4200 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4201 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4202 #if 1 4203 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4204 for (p = 0; p < 4; ++p) { 4205 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); 4206 } 4207 #endif 4208 /* C-G face */ 4209 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 4210 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4211 orntNew[0] = -2; 4212 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4213 orntNew[1] = -2; 4214 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4215 orntNew[2] = 0; 4216 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4217 orntNew[3] = 0; 4218 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4219 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4220 #if 1 4221 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4222 for (p = 0; p < 4; ++p) { 4223 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); 4224 } 4225 #endif 4226 /* B-H face */ 4227 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 4228 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4229 orntNew[0] = 0; 4230 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4231 orntNew[1] = -2; 4232 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4233 orntNew[2] = -2; 4234 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4235 orntNew[3] = 0; 4236 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4237 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4238 #if 1 4239 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4240 for (p = 0; p < 4; ++p) { 4241 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); 4242 } 4243 #endif 4244 for (r = 0; r < 12; ++r) { 4245 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 4246 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4247 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4248 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4249 #if 1 4250 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4251 for (p = 0; p < 2; ++p) { 4252 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); 4253 } 4254 #endif 4255 } 4256 } 4257 /* Split edges have 2 vertices and the same faces as the parent */ 4258 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4259 for (e = eStart; e < eEnd; ++e) { 4260 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4261 4262 for (r = 0; r < 2; ++r) { 4263 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4264 const PetscInt *cone, *ornt, *support; 4265 PetscInt coneNew[2], coneSize, c, supportSize, s; 4266 4267 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4268 coneNew[0] = vStartNew + (cone[0] - vStart); 4269 coneNew[1] = vStartNew + (cone[1] - vStart); 4270 coneNew[(r+1)%2] = newv; 4271 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4272 #if 1 4273 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4274 for (p = 0; p < 2; ++p) { 4275 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); 4276 } 4277 #endif 4278 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4279 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4280 for (s = 0; s < supportSize; ++s) { 4281 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4282 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4283 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4284 for (c = 0; c < coneSize; ++c) { 4285 if (cone[c] == e) break; 4286 } 4287 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 4288 } 4289 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4290 #if 1 4291 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4292 for (p = 0; p < supportSize; ++p) { 4293 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); 4294 } 4295 #endif 4296 } 4297 } 4298 /* Face edges have 2 vertices and 2+cells faces */ 4299 for (f = fStart; f < fEnd; ++f) { 4300 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}; 4301 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4302 const PetscInt *cone, *coneCell, *orntCell, *support; 4303 PetscInt coneNew[2], coneSize, c, supportSize, s; 4304 4305 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4306 for (r = 0; r < 4; ++r) { 4307 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4308 4309 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4310 coneNew[1] = newv; 4311 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4312 #if 1 4313 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4314 for (p = 0; p < 2; ++p) { 4315 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); 4316 } 4317 #endif 4318 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4319 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4320 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4321 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4322 for (s = 0; s < supportSize; ++s) { 4323 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4324 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4325 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4326 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4327 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4328 } 4329 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4330 #if 1 4331 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4332 for (p = 0; p < 2+supportSize; ++p) { 4333 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); 4334 } 4335 #endif 4336 } 4337 } 4338 /* Cell edges have 2 vertices and 4 faces */ 4339 for (c = cStart; c < cEnd; ++c) { 4340 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}; 4341 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4342 const PetscInt *cone; 4343 PetscInt coneNew[2], supportNew[4]; 4344 4345 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4346 for (r = 0; r < 6; ++r) { 4347 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4348 4349 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4350 coneNew[1] = newv; 4351 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4352 #if 1 4353 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4354 for (p = 0; p < 2; ++p) { 4355 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); 4356 } 4357 #endif 4358 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4359 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4360 #if 1 4361 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4362 for (p = 0; p < 4; ++p) { 4363 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); 4364 } 4365 #endif 4366 } 4367 } 4368 /* Old vertices have identical supports */ 4369 for (v = vStart; v < vEnd; ++v) { 4370 const PetscInt newp = vStartNew + (v - vStart); 4371 const PetscInt *support, *cone; 4372 PetscInt size, s; 4373 4374 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4375 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4376 for (s = 0; s < size; ++s) { 4377 PetscInt r = 0; 4378 4379 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4380 if (cone[1] == v) r = 1; 4381 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4382 } 4383 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4384 #if 1 4385 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4386 for (p = 0; p < size; ++p) { 4387 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); 4388 } 4389 #endif 4390 } 4391 /* Edge vertices have 2 + faces supports */ 4392 for (e = eStart; e < eEnd; ++e) { 4393 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4394 const PetscInt *cone, *support; 4395 PetscInt size, s; 4396 4397 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4398 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4399 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4400 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4401 for (s = 0; s < size; ++s) { 4402 PetscInt r; 4403 4404 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4405 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4406 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 4407 } 4408 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4409 #if 1 4410 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4411 for (p = 0; p < 2+size; ++p) { 4412 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); 4413 } 4414 #endif 4415 } 4416 /* Face vertices have 4 + cells supports */ 4417 for (f = fStart; f < fEnd; ++f) { 4418 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4419 const PetscInt *cone, *support; 4420 PetscInt size, s; 4421 4422 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4423 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4424 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4425 for (s = 0; s < size; ++s) { 4426 PetscInt r; 4427 4428 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4429 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4430 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 4431 } 4432 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4433 #if 1 4434 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4435 for (p = 0; p < 4+size; ++p) { 4436 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); 4437 } 4438 #endif 4439 } 4440 /* Cell vertices have 6 supports */ 4441 for (c = cStart; c < cEnd; ++c) { 4442 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4443 PetscInt supportNew[6]; 4444 4445 for (r = 0; r < 6; ++r) { 4446 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4447 } 4448 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4449 } 4450 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4451 break; 4452 case 8: 4453 /* Hybrid Hex 3D */ 4454 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4455 /* 4456 Bottom (viewed from top) Top 4457 1---------2---------2 7---------2---------6 4458 | | | | | | 4459 | B 2 C | | H 2 G | 4460 | | | | | | 4461 3----3----0----1----1 3----3----0----1----1 4462 | | | | | | 4463 | A 0 D | | E 0 F | 4464 | | | | | | 4465 0---------0---------3 4---------0---------5 4466 */ 4467 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4468 for (c = cStart; c < cMax; ++c) { 4469 const PetscInt newp = (c - cStart)*8; 4470 const PetscInt *cone, *ornt; 4471 PetscInt coneNew[6], orntNew[6]; 4472 4473 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4474 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4475 /* A hex */ 4476 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4477 orntNew[0] = ornt[0]; 4478 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4479 orntNew[1] = 0; 4480 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4481 orntNew[2] = ornt[2]; 4482 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4483 orntNew[3] = 0; 4484 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4485 orntNew[4] = 0; 4486 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4487 orntNew[5] = ornt[5]; 4488 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4489 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4490 #if 1 4491 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); 4492 for (p = 0; p < 6; ++p) { 4493 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); 4494 } 4495 #endif 4496 /* B hex */ 4497 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4498 orntNew[0] = ornt[0]; 4499 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4500 orntNew[1] = 0; 4501 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4502 orntNew[2] = -1; 4503 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4504 orntNew[3] = ornt[3]; 4505 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4506 orntNew[4] = 0; 4507 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4508 orntNew[5] = ornt[5]; 4509 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4510 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4511 #if 1 4512 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); 4513 for (p = 0; p < 6; ++p) { 4514 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); 4515 } 4516 #endif 4517 /* C hex */ 4518 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4519 orntNew[0] = ornt[0]; 4520 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4521 orntNew[1] = 0; 4522 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4523 orntNew[2] = -1; 4524 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4525 orntNew[3] = ornt[3]; 4526 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4527 orntNew[4] = ornt[4]; 4528 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4529 orntNew[5] = -4; 4530 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4531 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4532 #if 1 4533 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); 4534 for (p = 0; p < 6; ++p) { 4535 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); 4536 } 4537 #endif 4538 /* D hex */ 4539 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4540 orntNew[0] = ornt[0]; 4541 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4542 orntNew[1] = 0; 4543 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4544 orntNew[2] = ornt[2]; 4545 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4546 orntNew[3] = 0; 4547 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4548 orntNew[4] = ornt[4]; 4549 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4550 orntNew[5] = -4; 4551 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4552 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4553 #if 1 4554 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); 4555 for (p = 0; p < 6; ++p) { 4556 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); 4557 } 4558 #endif 4559 /* E hex */ 4560 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4561 orntNew[0] = -4; 4562 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4563 orntNew[1] = ornt[1]; 4564 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4565 orntNew[2] = ornt[2]; 4566 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4567 orntNew[3] = 0; 4568 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4569 orntNew[4] = -1; 4570 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4571 orntNew[5] = ornt[5]; 4572 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4573 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4574 #if 1 4575 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); 4576 for (p = 0; p < 6; ++p) { 4577 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); 4578 } 4579 #endif 4580 /* F hex */ 4581 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4582 orntNew[0] = -4; 4583 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4584 orntNew[1] = ornt[1]; 4585 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4586 orntNew[2] = ornt[2]; 4587 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4588 orntNew[3] = -1; 4589 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4590 orntNew[4] = ornt[4]; 4591 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4592 orntNew[5] = 1; 4593 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4594 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4595 #if 1 4596 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); 4597 for (p = 0; p < 6; ++p) { 4598 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); 4599 } 4600 #endif 4601 /* G hex */ 4602 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4603 orntNew[0] = -4; 4604 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4605 orntNew[1] = ornt[1]; 4606 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4607 orntNew[2] = 0; 4608 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4609 orntNew[3] = ornt[3]; 4610 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4611 orntNew[4] = ornt[4]; 4612 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4613 orntNew[5] = -3; 4614 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4615 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4616 #if 1 4617 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); 4618 for (p = 0; p < 6; ++p) { 4619 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); 4620 } 4621 #endif 4622 /* H hex */ 4623 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4624 orntNew[0] = -4; 4625 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4626 orntNew[1] = ornt[1]; 4627 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4628 orntNew[2] = -1; 4629 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4630 orntNew[3] = ornt[3]; 4631 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4632 orntNew[4] = 3; 4633 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4634 orntNew[5] = ornt[5]; 4635 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4636 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4637 #if 1 4638 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); 4639 for (p = 0; p < 6; ++p) { 4640 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); 4641 } 4642 #endif 4643 } 4644 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4645 /* 4646 3---------2---------2 4647 | | | 4648 | D 2 C | 4649 | | | 4650 3----3----0----1----1 4651 | | | 4652 | A 0 B | 4653 | | | 4654 0---------0---------1 4655 */ 4656 for (c = cMax; c < cEnd; ++c) { 4657 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4658 const PetscInt *cone, *ornt, *fornt; 4659 PetscInt coneNew[6], orntNew[6], o, of, i; 4660 4661 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4662 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4663 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4664 o = ornt[0] < 0 ? -1 : 1; 4665 for (r = 0; r < 4; ++r) { 4666 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4667 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4668 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 4669 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]); 4670 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4671 orntNew[0] = ornt[0]; 4672 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4673 orntNew[1] = ornt[0]; 4674 of = fornt[edgeA] < 0 ? -1 : 1; 4675 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 4676 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 4677 orntNew[i] = ornt[edgeA]; 4678 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 4679 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4680 orntNew[i] = 0; 4681 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 4682 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4683 orntNew[i] = -2; 4684 of = fornt[edgeB] < 0 ? -1 : 1; 4685 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 4686 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 4687 orntNew[i] = ornt[edgeB]; 4688 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4689 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4690 #if 1 4691 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); 4692 for (p = 0; p < 2; ++p) { 4693 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); 4694 } 4695 for (p = 2; p < 6; ++p) { 4696 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); 4697 } 4698 #endif 4699 } 4700 } 4701 /* Interior split faces have 4 edges and the same cells as the parent */ 4702 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4703 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 4704 for (f = fStart; f < fMax; ++f) { 4705 for (r = 0; r < 4; ++r) { 4706 /* TODO: This can come from GetFaces_Internal() */ 4707 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}; 4708 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4709 const PetscInt *cone, *ornt, *support; 4710 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4711 4712 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4713 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4714 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4715 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4716 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4717 orntNew[(r+0)%4] = ornt[r]; 4718 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4719 orntNew[(r+1)%4] = 0; 4720 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4721 orntNew[(r+2)%4] = -2; 4722 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4723 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4724 #if 1 4725 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4726 for (p = 0; p < 4; ++p) { 4727 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); 4728 } 4729 #endif 4730 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4731 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4732 for (s = 0; s < supportSize; ++s) { 4733 PetscInt subf; 4734 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4735 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4736 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4737 for (c = 0; c < coneSize; ++c) { 4738 if (cone[c] == f) break; 4739 } 4740 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4741 if (support[s] < cMax) { 4742 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4743 } else { 4744 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4745 } 4746 } 4747 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4748 #if 1 4749 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4750 for (p = 0; p < supportSize; ++p) { 4751 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); 4752 } 4753 #endif 4754 } 4755 } 4756 /* Interior cell faces have 4 edges and 2 cells */ 4757 for (c = cStart; c < cMax; ++c) { 4758 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}; 4759 const PetscInt *cone, *ornt; 4760 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4761 4762 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4763 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4764 /* A-D face */ 4765 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4766 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4767 orntNew[0] = 0; 4768 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4769 orntNew[1] = 0; 4770 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4771 orntNew[2] = -2; 4772 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4773 orntNew[3] = -2; 4774 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4775 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4776 #if 1 4777 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4778 for (p = 0; p < 4; ++p) { 4779 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); 4780 } 4781 #endif 4782 /* C-D face */ 4783 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4784 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4785 orntNew[0] = 0; 4786 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4787 orntNew[1] = 0; 4788 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4789 orntNew[2] = -2; 4790 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4791 orntNew[3] = -2; 4792 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4793 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4794 #if 1 4795 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4796 for (p = 0; p < 4; ++p) { 4797 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); 4798 } 4799 #endif 4800 /* B-C face */ 4801 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4802 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4803 orntNew[0] = -2; 4804 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4805 orntNew[1] = 0; 4806 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4807 orntNew[2] = 0; 4808 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4809 orntNew[3] = -2; 4810 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4811 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4812 #if 1 4813 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4814 for (p = 0; p < 4; ++p) { 4815 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); 4816 } 4817 #endif 4818 /* A-B face */ 4819 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4820 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4821 orntNew[0] = -2; 4822 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4823 orntNew[1] = 0; 4824 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4825 orntNew[2] = 0; 4826 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4827 orntNew[3] = -2; 4828 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4829 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4830 #if 1 4831 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4832 for (p = 0; p < 4; ++p) { 4833 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); 4834 } 4835 #endif 4836 /* E-F face */ 4837 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4838 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4839 orntNew[0] = -2; 4840 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4841 orntNew[1] = -2; 4842 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4843 orntNew[2] = 0; 4844 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4845 orntNew[3] = 0; 4846 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4847 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4848 #if 1 4849 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4850 for (p = 0; p < 4; ++p) { 4851 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); 4852 } 4853 #endif 4854 /* F-G face */ 4855 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4856 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4857 orntNew[0] = -2; 4858 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4859 orntNew[1] = -2; 4860 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4861 orntNew[2] = 0; 4862 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4863 orntNew[3] = 0; 4864 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4865 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4866 #if 1 4867 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4868 for (p = 0; p < 4; ++p) { 4869 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); 4870 } 4871 #endif 4872 /* G-H face */ 4873 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4874 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4875 orntNew[0] = -2; 4876 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4877 orntNew[1] = 0; 4878 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4879 orntNew[2] = 0; 4880 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4881 orntNew[3] = -2; 4882 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4883 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4884 #if 1 4885 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4886 for (p = 0; p < 4; ++p) { 4887 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); 4888 } 4889 #endif 4890 /* E-H face */ 4891 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4892 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4893 orntNew[0] = -2; 4894 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4895 orntNew[1] = -2; 4896 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4897 orntNew[2] = 0; 4898 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4899 orntNew[3] = 0; 4900 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4901 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4902 #if 1 4903 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4904 for (p = 0; p < 4; ++p) { 4905 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); 4906 } 4907 #endif 4908 /* A-E face */ 4909 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4910 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4911 orntNew[0] = 0; 4912 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4913 orntNew[1] = 0; 4914 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4915 orntNew[2] = -2; 4916 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4917 orntNew[3] = -2; 4918 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4919 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4920 #if 1 4921 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4922 for (p = 0; p < 4; ++p) { 4923 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); 4924 } 4925 #endif 4926 /* D-F face */ 4927 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4928 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4929 orntNew[0] = -2; 4930 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4931 orntNew[1] = 0; 4932 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4933 orntNew[2] = 0; 4934 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4935 orntNew[3] = -2; 4936 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4937 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4938 #if 1 4939 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4940 for (p = 0; p < 4; ++p) { 4941 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); 4942 } 4943 #endif 4944 /* C-G face */ 4945 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4946 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4947 orntNew[0] = -2; 4948 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4949 orntNew[1] = -2; 4950 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4951 orntNew[2] = 0; 4952 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4953 orntNew[3] = 0; 4954 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4955 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4956 #if 1 4957 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4958 for (p = 0; p < 4; ++p) { 4959 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); 4960 } 4961 #endif 4962 /* B-H face */ 4963 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 4964 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4965 orntNew[0] = 0; 4966 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4967 orntNew[1] = -2; 4968 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4969 orntNew[2] = -2; 4970 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4971 orntNew[3] = 0; 4972 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4973 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4974 #if 1 4975 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4976 for (p = 0; p < 4; ++p) { 4977 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); 4978 } 4979 #endif 4980 for (r = 0; r < 12; ++r) { 4981 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 4982 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4983 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4984 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4985 #if 1 4986 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4987 for (p = 0; p < 2; ++p) { 4988 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); 4989 } 4990 #endif 4991 } 4992 } 4993 /* Hybrid split faces have 4 edges and same cells */ 4994 for (f = fMax; f < fEnd; ++f) { 4995 const PetscInt *cone, *ornt, *support; 4996 PetscInt coneNew[4], orntNew[4]; 4997 PetscInt supportNew[2], size, s, c; 4998 4999 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5000 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5001 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5002 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5003 for (r = 0; r < 2; ++r) { 5004 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 5005 5006 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 5007 orntNew[0] = ornt[0]; 5008 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 5009 orntNew[1] = ornt[1]; 5010 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 5011 orntNew[2+r] = 0; 5012 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5013 orntNew[3-r] = 0; 5014 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5015 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5016 #if 1 5017 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 5018 for (p = 0; p < 2; ++p) { 5019 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); 5020 } 5021 for (p = 2; p < 4; ++p) { 5022 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); 5023 } 5024 #endif 5025 for (s = 0; s < size; ++s) { 5026 const PetscInt *coneCell, *orntCell, *fornt; 5027 PetscInt o, of; 5028 5029 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5030 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5031 o = orntCell[0] < 0 ? -1 : 1; 5032 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 5033 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 5034 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 5035 of = fornt[c-2] < 0 ? -1 : 1; 5036 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 5037 } 5038 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5039 #if 1 5040 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 5041 for (p = 0; p < size; ++p) { 5042 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); 5043 } 5044 #endif 5045 } 5046 } 5047 /* Hybrid cell faces have 4 edges and 2 cells */ 5048 for (c = cMax; c < cEnd; ++c) { 5049 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 5050 const PetscInt *cone, *ornt; 5051 PetscInt coneNew[4], orntNew[4]; 5052 PetscInt supportNew[2]; 5053 5054 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5055 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5056 for (r = 0; r < 4; ++r) { 5057 #if 0 5058 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 5059 orntNew[0] = 0; 5060 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 5061 orntNew[1] = 0; 5062 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 5063 orntNew[2] = 0; 5064 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5065 orntNew[3] = 0; 5066 #else 5067 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 5068 orntNew[0] = 0; 5069 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 5070 orntNew[1] = 0; 5071 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 5072 orntNew[2] = 0; 5073 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5074 orntNew[3] = 0; 5075 #endif 5076 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 5077 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 5078 #if 1 5079 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); 5080 for (p = 0; p < 2; ++p) { 5081 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); 5082 } 5083 for (p = 2; p < 4; ++p) { 5084 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); 5085 } 5086 #endif 5087 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 5088 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 5089 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 5090 #if 1 5091 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); 5092 for (p = 0; p < 2; ++p) { 5093 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); 5094 } 5095 #endif 5096 } 5097 } 5098 /* Interior split edges have 2 vertices and the same faces as the parent */ 5099 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5100 for (e = eStart; e < eMax; ++e) { 5101 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5102 5103 for (r = 0; r < 2; ++r) { 5104 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5105 const PetscInt *cone, *ornt, *support; 5106 PetscInt coneNew[2], coneSize, c, supportSize, s; 5107 5108 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5109 coneNew[0] = vStartNew + (cone[0] - vStart); 5110 coneNew[1] = vStartNew + (cone[1] - vStart); 5111 coneNew[(r+1)%2] = newv; 5112 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5113 #if 1 5114 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5115 for (p = 0; p < 2; ++p) { 5116 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); 5117 } 5118 #endif 5119 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5120 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5121 for (s = 0; s < supportSize; ++s) { 5122 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5123 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5124 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5125 for (c = 0; c < coneSize; ++c) { 5126 if (cone[c] == e) break; 5127 } 5128 if (support[s] < fMax) { 5129 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 5130 } else { 5131 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 5132 } 5133 } 5134 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5135 #if 1 5136 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5137 for (p = 0; p < supportSize; ++p) { 5138 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); 5139 } 5140 #endif 5141 } 5142 } 5143 /* Interior face edges have 2 vertices and 2+cells faces */ 5144 for (f = fStart; f < fMax; ++f) { 5145 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}; 5146 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5147 const PetscInt *cone, *coneCell, *orntCell, *support; 5148 PetscInt coneNew[2], coneSize, c, supportSize, s; 5149 5150 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5151 for (r = 0; r < 4; ++r) { 5152 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5153 5154 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5155 coneNew[1] = newv; 5156 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5157 #if 1 5158 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5159 for (p = 0; p < 2; ++p) { 5160 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); 5161 } 5162 #endif 5163 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5164 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5165 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5166 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5167 for (s = 0; s < supportSize; ++s) { 5168 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5169 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5170 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5171 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5172 if (support[s] < cMax) { 5173 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5174 } else { 5175 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 5176 } 5177 } 5178 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5179 #if 1 5180 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5181 for (p = 0; p < 2+supportSize; ++p) { 5182 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); 5183 } 5184 #endif 5185 } 5186 } 5187 /* Interior cell edges have 2 vertices and 4 faces */ 5188 for (c = cStart; c < cMax; ++c) { 5189 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}; 5190 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5191 const PetscInt *cone; 5192 PetscInt coneNew[2], supportNew[4]; 5193 5194 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5195 for (r = 0; r < 6; ++r) { 5196 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5197 5198 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5199 coneNew[1] = newv; 5200 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5201 #if 1 5202 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5203 for (p = 0; p < 2; ++p) { 5204 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); 5205 } 5206 #endif 5207 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5208 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5209 #if 1 5210 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5211 for (p = 0; p < 4; ++p) { 5212 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); 5213 } 5214 #endif 5215 } 5216 } 5217 /* Hybrid edges have two vertices and the same faces */ 5218 for (e = eMax; e < eEnd; ++e) { 5219 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5220 const PetscInt *cone, *support, *fcone; 5221 PetscInt coneNew[2], size, fsize, s; 5222 5223 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5224 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5225 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5226 coneNew[0] = vStartNew + (cone[0] - vStart); 5227 coneNew[1] = vStartNew + (cone[1] - vStart); 5228 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5229 #if 1 5230 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5231 for (p = 0; p < 2; ++p) { 5232 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); 5233 } 5234 #endif 5235 for (s = 0; s < size; ++s) { 5236 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5237 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5238 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5239 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5240 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 5241 } 5242 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5243 #if 1 5244 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5245 for (p = 0; p < size; ++p) { 5246 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); 5247 } 5248 #endif 5249 } 5250 /* Hybrid face edges have 2 vertices and 2+cells faces */ 5251 for (f = fMax; f < fEnd; ++f) { 5252 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5253 const PetscInt *cone, *support, *ccone, *cornt; 5254 PetscInt coneNew[2], size, csize, s; 5255 5256 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5257 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5258 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5259 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5260 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 5261 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5262 #if 1 5263 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5264 for (p = 0; p < 2; ++p) { 5265 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); 5266 } 5267 #endif 5268 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 5269 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5270 for (s = 0; s < size; ++s) { 5271 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5272 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5273 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5274 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5275 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]); 5276 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 5277 } 5278 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5279 #if 1 5280 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5281 for (p = 0; p < 2+size; ++p) { 5282 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); 5283 } 5284 #endif 5285 } 5286 /* Hybrid cell edges have 2 vertices and 4 faces */ 5287 for (c = cMax; c < cEnd; ++c) { 5288 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5289 const PetscInt *cone, *support; 5290 PetscInt coneNew[2], size; 5291 5292 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5293 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5294 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5295 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5296 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5297 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5298 #if 1 5299 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5300 for (p = 0; p < 2; ++p) { 5301 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); 5302 } 5303 #endif 5304 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5305 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5306 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5307 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5308 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5309 #if 1 5310 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5311 for (p = 0; p < 4; ++p) { 5312 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); 5313 } 5314 #endif 5315 } 5316 /* Interior vertices have identical supports */ 5317 for (v = vStart; v < vEnd; ++v) { 5318 const PetscInt newp = vStartNew + (v - vStart); 5319 const PetscInt *support, *cone; 5320 PetscInt size, s; 5321 5322 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5323 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5324 for (s = 0; s < size; ++s) { 5325 PetscInt r = 0; 5326 5327 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5328 if (cone[1] == v) r = 1; 5329 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5330 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5331 } 5332 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5333 #if 1 5334 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5335 for (p = 0; p < size; ++p) { 5336 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); 5337 } 5338 #endif 5339 } 5340 /* Interior edge vertices have 2 + faces supports */ 5341 for (e = eStart; e < eMax; ++e) { 5342 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5343 const PetscInt *cone, *support; 5344 PetscInt size, s; 5345 5346 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5347 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5348 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5349 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5350 for (s = 0; s < size; ++s) { 5351 PetscInt r; 5352 5353 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5354 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5355 if (support[s] < fMax) { 5356 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5357 } else { 5358 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5359 } 5360 } 5361 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5362 #if 1 5363 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5364 for (p = 0; p < 2+size; ++p) { 5365 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); 5366 } 5367 #endif 5368 } 5369 /* Interior face vertices have 4 + cells supports */ 5370 for (f = fStart; f < fMax; ++f) { 5371 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5372 const PetscInt *cone, *support; 5373 PetscInt size, s; 5374 5375 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5376 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5377 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5378 for (s = 0; s < size; ++s) { 5379 PetscInt r; 5380 5381 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5382 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5383 if (support[s] < cMax) { 5384 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5385 } else { 5386 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5387 } 5388 } 5389 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5390 #if 1 5391 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5392 for (p = 0; p < 4+size; ++p) { 5393 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); 5394 } 5395 #endif 5396 } 5397 /* Cell vertices have 6 supports */ 5398 for (c = cStart; c < cMax; ++c) { 5399 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5400 PetscInt supportNew[6]; 5401 5402 for (r = 0; r < 6; ++r) { 5403 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5404 } 5405 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5406 } 5407 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5408 break; 5409 default: 5410 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5411 } 5412 PetscFunctionReturn(0); 5413 } 5414 5415 #undef __FUNCT__ 5416 #define __FUNCT__ "CellRefinerSetCoordinates" 5417 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5418 { 5419 PetscSection coordSection, coordSectionNew; 5420 Vec coordinates, coordinatesNew; 5421 PetscScalar *coords, *coordsNew; 5422 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5423 PetscInt spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5424 PetscErrorCode ierr; 5425 5426 PetscFunctionBegin; 5427 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5428 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5429 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5430 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5431 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5432 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5433 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5434 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5435 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5436 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 5437 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5438 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5439 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 5440 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5441 if (cMax < 0) cMax = cEnd; 5442 if (fMax < 0) fMax = fEnd; 5443 if (eMax < 0) eMax = eEnd; 5444 /* All vertices have the spaceDim coordinates */ 5445 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5446 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 5447 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 5448 } 5449 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5450 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 5451 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5452 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5453 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 5454 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5455 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5456 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 5457 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 5458 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 5459 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5460 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5461 switch (refiner) { 5462 case 0: break; 5463 case 6: /* Hex 3D */ 5464 case 8: /* Hybrid Hex 3D */ 5465 /* Face vertices have the average of corner coordinates */ 5466 for (f = fStart; f < fMax; ++f) { 5467 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5468 PetscInt *cone = NULL; 5469 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5470 5471 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5472 for (p = 0; p < closureSize*2; p += 2) { 5473 const PetscInt point = cone[p]; 5474 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5475 } 5476 for (v = 0; v < coneSize; ++v) { 5477 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5478 } 5479 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5480 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5481 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5482 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5483 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5484 } 5485 case 2: /* Hex 2D */ 5486 case 4: /* Hybrid Hex 2D */ 5487 /* Cell vertices have the average of corner coordinates */ 5488 for (c = cStart; c < cMax; ++c) { 5489 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (spaceDim > 2 ? (fMax - fStart) : 0); 5490 PetscInt *cone = NULL; 5491 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5492 5493 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5494 for (p = 0; p < closureSize*2; p += 2) { 5495 const PetscInt point = cone[p]; 5496 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5497 } 5498 for (v = 0; v < coneSize; ++v) { 5499 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5500 } 5501 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5502 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5503 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5504 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5505 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5506 } 5507 case 1: /* Simplicial 2D */ 5508 case 3: /* Hybrid Simplicial 2D */ 5509 case 5: /* Simplicial 3D */ 5510 case 7: /* Hybrid Simplicial 3D */ 5511 /* Edge vertices have the average of endpoint coordinates */ 5512 for (e = eStart; e < eMax; ++e) { 5513 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5514 const PetscInt *cone; 5515 PetscInt coneSize, offA, offB, offnew, d; 5516 5517 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5518 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5519 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5520 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5521 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5522 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5523 ierr = DMPlexLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 5524 for (d = 0; d < spaceDim; ++d) { 5525 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 5526 } 5527 } 5528 /* Old vertices have the same coordinates */ 5529 for (v = vStart; v < vEnd; ++v) { 5530 const PetscInt newv = vStartNew + (v - vStart); 5531 PetscInt off, offnew, d; 5532 5533 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5534 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5535 for (d = 0; d < spaceDim; ++d) { 5536 coordsNew[offnew+d] = coords[off+d]; 5537 } 5538 } 5539 break; 5540 default: 5541 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5542 } 5543 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5544 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5545 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5546 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5547 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5548 if (dm->maxCell) { 5549 const PetscReal *maxCell, *L; 5550 ierr = DMGetPeriodicity(dm, &maxCell, &L);CHKERRQ(ierr); 5551 ierr = DMSetPeriodicity(rdm, maxCell, L);CHKERRQ(ierr); 5552 } 5553 PetscFunctionReturn(0); 5554 } 5555 5556 #undef __FUNCT__ 5557 #define __FUNCT__ "DMPlexCreateProcessSF" 5558 /*@ 5559 DMPlexCreateProcessSF - Create an SF which just has process connectivity 5560 5561 Collective on DM 5562 5563 Input Parameters: 5564 + dm - The DM 5565 - sfPoint - The PetscSF which encodes point connectivity 5566 5567 Output Parameters: 5568 + processRanks - A list of process neighbors, or NULL 5569 - sfProcess - An SF encoding the process connectivity, or NULL 5570 5571 Level: developer 5572 5573 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 5574 @*/ 5575 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5576 { 5577 PetscInt numRoots, numLeaves, l; 5578 const PetscInt *localPoints; 5579 const PetscSFNode *remotePoints; 5580 PetscInt *localPointsNew; 5581 PetscSFNode *remotePointsNew; 5582 PetscInt *ranks, *ranksNew; 5583 PetscMPIInt numProcs; 5584 PetscErrorCode ierr; 5585 5586 PetscFunctionBegin; 5587 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5588 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 5589 if (processRanks) {PetscValidPointer(processRanks, 3);} 5590 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 5591 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &numProcs);CHKERRQ(ierr); 5592 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5593 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5594 for (l = 0; l < numLeaves; ++l) { 5595 ranks[l] = remotePoints[l].rank; 5596 } 5597 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5598 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5599 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5600 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5601 for (l = 0; l < numLeaves; ++l) { 5602 ranksNew[l] = ranks[l]; 5603 localPointsNew[l] = l; 5604 remotePointsNew[l].index = 0; 5605 remotePointsNew[l].rank = ranksNew[l]; 5606 } 5607 ierr = PetscFree(ranks);CHKERRQ(ierr); 5608 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 5609 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 5610 if (sfProcess) { 5611 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5612 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 5613 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5614 ierr = PetscSFSetGraph(*sfProcess, numProcs, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5615 } 5616 PetscFunctionReturn(0); 5617 } 5618 5619 #undef __FUNCT__ 5620 #define __FUNCT__ "CellRefinerCreateSF" 5621 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5622 { 5623 PetscSF sf, sfNew, sfProcess; 5624 IS processRanks; 5625 MPI_Datatype depthType; 5626 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5627 const PetscInt *localPoints, *neighbors; 5628 const PetscSFNode *remotePoints; 5629 PetscInt *localPointsNew; 5630 PetscSFNode *remotePointsNew; 5631 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5632 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5633 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5634 PetscErrorCode ierr; 5635 5636 PetscFunctionBegin; 5637 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5638 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5639 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5640 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5641 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5642 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5643 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5644 cMax = cMax < 0 ? cEnd : cMax; 5645 fMax = fMax < 0 ? fEnd : fMax; 5646 eMax = eMax < 0 ? eEnd : eMax; 5647 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5648 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5649 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5650 /* Calculate size of new SF */ 5651 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5652 if (numRoots < 0) PetscFunctionReturn(0); 5653 for (l = 0; l < numLeaves; ++l) { 5654 const PetscInt p = localPoints[l]; 5655 5656 switch (refiner) { 5657 case 1: 5658 case 3: 5659 /* Hybrid Simplicial 2D */ 5660 if ((p >= vStart) && (p < vEnd)) { 5661 /* Interior vertices stay the same */ 5662 ++numLeavesNew; 5663 } else if ((p >= fStart) && (p < fMax)) { 5664 /* Interior faces add new faces and vertex */ 5665 numLeavesNew += 2 + 1; 5666 } else if ((p >= fMax) && (p < fEnd)) { 5667 /* Hybrid faces stay the same */ 5668 ++numLeavesNew; 5669 } else if ((p >= cStart) && (p < cMax)) { 5670 /* Interior cells add new cells and interior faces */ 5671 numLeavesNew += 4 + 3; 5672 } else if ((p >= cMax) && (p < cEnd)) { 5673 /* Hybrid cells add new cells and hybrid face */ 5674 numLeavesNew += 2 + 1; 5675 } 5676 break; 5677 case 2: 5678 case 4: 5679 /* Hybrid Hex 2D */ 5680 if ((p >= vStart) && (p < vEnd)) { 5681 /* Interior vertices stay the same */ 5682 ++numLeavesNew; 5683 } else if ((p >= fStart) && (p < fMax)) { 5684 /* Interior faces add new faces and vertex */ 5685 numLeavesNew += 2 + 1; 5686 } else if ((p >= fMax) && (p < fEnd)) { 5687 /* Hybrid faces stay the same */ 5688 ++numLeavesNew; 5689 } else if ((p >= cStart) && (p < cMax)) { 5690 /* Interior cells add new cells, interior faces, and vertex */ 5691 numLeavesNew += 4 + 4 + 1; 5692 } else if ((p >= cMax) && (p < cEnd)) { 5693 /* Hybrid cells add new cells and hybrid face */ 5694 numLeavesNew += 2 + 1; 5695 } 5696 break; 5697 case 5: 5698 case 7: 5699 /* Hybrid Simplicial 3D */ 5700 if ((p >= vStart) && (p < vEnd)) { 5701 /* Interior vertices stay the same */ 5702 ++numLeavesNew; 5703 } else if ((p >= eStart) && (p < eMax)) { 5704 /* Interior edges add new edges and vertex */ 5705 numLeavesNew += 2 + 1; 5706 } else if ((p >= eMax) && (p < eEnd)) { 5707 /* Hybrid edges stay the same */ 5708 ++numLeavesNew; 5709 } else if ((p >= fStart) && (p < fMax)) { 5710 /* Interior faces add new faces and edges */ 5711 numLeavesNew += 4 + 3; 5712 } else if ((p >= fMax) && (p < fEnd)) { 5713 /* Hybrid faces add new faces and edges */ 5714 numLeavesNew += 2 + 1; 5715 } else if ((p >= cStart) && (p < cMax)) { 5716 /* Interior cells add new cells, faces, and edges */ 5717 numLeavesNew += 8 + 8 + 1; 5718 } else if ((p >= cMax) && (p < cEnd)) { 5719 /* Hybrid cells add new cells and faces */ 5720 numLeavesNew += 4 + 3; 5721 } 5722 break; 5723 case 6: 5724 case 8: 5725 /* Hybrid Hex 3D */ 5726 if ((p >= vStart) && (p < vEnd)) { 5727 /* Old vertices stay the same */ 5728 ++numLeavesNew; 5729 } else if ((p >= eStart) && (p < eMax)) { 5730 /* Interior edges add new edges, and vertex */ 5731 numLeavesNew += 2 + 1; 5732 } else if ((p >= eMax) && (p < eEnd)) { 5733 /* Hybrid edges stay the same */ 5734 ++numLeavesNew; 5735 } else if ((p >= fStart) && (p < fMax)) { 5736 /* Interior faces add new faces, edges, and vertex */ 5737 numLeavesNew += 4 + 4 + 1; 5738 } else if ((p >= fMax) && (p < fEnd)) { 5739 /* Hybrid faces add new faces and edges */ 5740 numLeavesNew += 2 + 1; 5741 } else if ((p >= cStart) && (p < cMax)) { 5742 /* Interior cells add new cells, faces, edges, and vertex */ 5743 numLeavesNew += 8 + 12 + 6 + 1; 5744 } else if ((p >= cStart) && (p < cEnd)) { 5745 /* Hybrid cells add new cells, faces, and edges */ 5746 numLeavesNew += 4 + 4 + 1; 5747 } 5748 break; 5749 default: 5750 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5751 } 5752 } 5753 /* Communicate depthSizes for each remote rank */ 5754 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5755 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5756 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5757 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5758 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5759 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5760 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5761 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5762 for (n = 0; n < numNeighbors; ++n) { 5763 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5764 } 5765 depthSizeOld[depth] = cMax; 5766 depthSizeOld[0] = vMax; 5767 depthSizeOld[depth-1] = fMax; 5768 depthSizeOld[1] = eMax; 5769 5770 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5771 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5772 5773 depthSizeOld[depth] = cEnd - cStart; 5774 depthSizeOld[0] = vEnd - vStart; 5775 depthSizeOld[depth-1] = fEnd - fStart; 5776 depthSizeOld[1] = eEnd - eStart; 5777 5778 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5779 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5780 for (n = 0; n < numNeighbors; ++n) { 5781 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5782 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 5783 rdepthMaxOld[n*(depth+1)+depth-1] = rdepthMaxOld[n*(depth+1)+depth-1] < 0 ? rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n]: rdepthMaxOld[n*(depth+1)+depth-1]; 5784 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 5785 } 5786 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5787 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5788 /* Calculate new point SF */ 5789 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5790 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5791 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5792 for (l = 0, m = 0; l < numLeaves; ++l) { 5793 PetscInt p = localPoints[l]; 5794 PetscInt rp = remotePoints[l].index, n; 5795 PetscMPIInt rrank = remotePoints[l].rank; 5796 5797 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5798 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5799 switch (refiner) { 5800 case 1: 5801 case 3: 5802 /* Hybrid simplicial 2D */ 5803 if ((p >= vStart) && (p < vEnd)) { 5804 /* Old vertices stay the same */ 5805 localPointsNew[m] = vStartNew + (p - vStart); 5806 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5807 remotePointsNew[m].rank = rrank; 5808 ++m; 5809 } else if ((p >= fStart) && (p < fMax)) { 5810 /* Old interior faces add new faces and vertex */ 5811 for (r = 0; r < 2; ++r, ++m) { 5812 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5813 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5814 remotePointsNew[m].rank = rrank; 5815 } 5816 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5817 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5818 remotePointsNew[m].rank = rrank; 5819 ++m; 5820 } else if ((p >= fMax) && (p < fEnd)) { 5821 /* Old hybrid faces stay the same */ 5822 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5823 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5824 remotePointsNew[m].rank = rrank; 5825 ++m; 5826 } else if ((p >= cStart) && (p < cMax)) { 5827 /* Old interior cells add new cells and interior faces */ 5828 for (r = 0; r < 4; ++r, ++m) { 5829 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5830 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5831 remotePointsNew[m].rank = rrank; 5832 } 5833 for (r = 0; r < 3; ++r, ++m) { 5834 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5835 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5836 remotePointsNew[m].rank = rrank; 5837 } 5838 } else if ((p >= cMax) && (p < cEnd)) { 5839 /* Old hybrid cells add new cells and hybrid face */ 5840 for (r = 0; r < 2; ++r, ++m) { 5841 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5842 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5843 remotePointsNew[m].rank = rrank; 5844 } 5845 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5846 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]); 5847 remotePointsNew[m].rank = rrank; 5848 ++m; 5849 } 5850 break; 5851 case 2: 5852 case 4: 5853 /* Hybrid Hex 2D */ 5854 if ((p >= vStart) && (p < vEnd)) { 5855 /* Old vertices stay the same */ 5856 localPointsNew[m] = vStartNew + (p - vStart); 5857 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5858 remotePointsNew[m].rank = rrank; 5859 ++m; 5860 } else if ((p >= fStart) && (p < fMax)) { 5861 /* Old interior faces add new faces and vertex */ 5862 for (r = 0; r < 2; ++r, ++m) { 5863 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5864 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5865 remotePointsNew[m].rank = rrank; 5866 } 5867 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5868 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5869 remotePointsNew[m].rank = rrank; 5870 ++m; 5871 } else if ((p >= fMax) && (p < fEnd)) { 5872 /* Old hybrid faces stay the same */ 5873 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5874 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5875 remotePointsNew[m].rank = rrank; 5876 ++m; 5877 } else if ((p >= cStart) && (p < cMax)) { 5878 /* Old interior cells add new cells, interior faces, and vertex */ 5879 for (r = 0; r < 4; ++r, ++m) { 5880 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5881 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5882 remotePointsNew[m].rank = rrank; 5883 } 5884 for (r = 0; r < 4; ++r, ++m) { 5885 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5886 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5887 remotePointsNew[m].rank = rrank; 5888 } 5889 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 5890 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 5891 remotePointsNew[m].rank = rrank; 5892 ++m; 5893 } else if ((p >= cStart) && (p < cMax)) { 5894 /* Old hybrid cells add new cells and hybrid face */ 5895 for (r = 0; r < 2; ++r, ++m) { 5896 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5897 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5898 remotePointsNew[m].rank = rrank; 5899 } 5900 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5901 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth]); 5902 remotePointsNew[m].rank = rrank; 5903 ++m; 5904 } 5905 break; 5906 case 5: 5907 case 7: 5908 /* Hybrid Simplicial 3D */ 5909 if ((p >= vStart) && (p < vEnd)) { 5910 /* Interior vertices stay the same */ 5911 localPointsNew[m] = vStartNew + (p - vStart); 5912 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5913 remotePointsNew[m].rank = rrank; 5914 ++m; 5915 } else if ((p >= eStart) && (p < eMax)) { 5916 /* Interior edges add new edges and vertex */ 5917 for (r = 0; r < 2; ++r, ++m) { 5918 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5919 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5920 remotePointsNew[m].rank = rrank; 5921 } 5922 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5923 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5924 remotePointsNew[m].rank = rrank; 5925 ++m; 5926 } else if ((p >= eMax) && (p < eEnd)) { 5927 /* Hybrid edges stay the same */ 5928 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5929 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rp - rdepthMaxOld[n*(depth+1)+1]); 5930 remotePointsNew[m].rank = rrank; 5931 ++m; 5932 } else if ((p >= fStart) && (p < fMax)) { 5933 /* Interior faces add new faces and edges */ 5934 for (r = 0; r < 4; ++r, ++m) { 5935 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5936 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5937 remotePointsNew[m].rank = rrank; 5938 } 5939 for (r = 0; r < 3; ++r, ++m) { 5940 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5941 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5942 remotePointsNew[m].rank = rrank; 5943 } 5944 } else if ((p >= fMax) && (p < fEnd)) { 5945 /* Hybrid faces add new faces and edges */ 5946 for (r = 0; r < 2; ++r, ++m) { 5947 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5948 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; 5949 remotePointsNew[m].rank = rrank; 5950 } 5951 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 5952 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5953 remotePointsNew[m].rank = rrank; 5954 ++m; 5955 } else if ((p >= cStart) && (p < cMax)) { 5956 /* Interior cells add new cells, faces, and edges */ 5957 for (r = 0; r < 8; ++r, ++m) { 5958 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5959 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5960 remotePointsNew[m].rank = rrank; 5961 } 5962 for (r = 0; r < 8; ++r, ++m) { 5963 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5964 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 5965 remotePointsNew[m].rank = rrank; 5966 } 5967 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 5968 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 + 0; 5969 remotePointsNew[m].rank = rrank; 5970 ++m; 5971 } else if ((p >= cMax) && (p < cEnd)) { 5972 /* Hybrid cells add new cells and faces */ 5973 for (r = 0; r < 4; ++r, ++m) { 5974 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5975 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5976 remotePointsNew[m].rank = rrank; 5977 } 5978 for (r = 0; r < 3; ++r, ++m) { 5979 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5980 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; 5981 remotePointsNew[m].rank = rrank; 5982 } 5983 } 5984 break; 5985 case 6: 5986 case 8: 5987 /* Hybrid Hex 3D */ 5988 if ((p >= vStart) && (p < vEnd)) { 5989 /* Interior vertices stay the same */ 5990 localPointsNew[m] = vStartNew + (p - vStart); 5991 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5992 remotePointsNew[m].rank = rrank; 5993 ++m; 5994 } else if ((p >= eStart) && (p < eMax)) { 5995 /* Interior edges add new edges and vertex */ 5996 for (r = 0; r < 2; ++r, ++m) { 5997 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5998 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5999 remotePointsNew[m].rank = rrank; 6000 } 6001 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6002 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6003 remotePointsNew[m].rank = rrank; 6004 ++m; 6005 } else if ((p >= eMax) && (p < eEnd)) { 6006 /* Hybrid edges stay the same */ 6007 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6008 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 + (rp - rdepthMaxOld[n*(depth+1)+1]); 6009 remotePointsNew[m].rank = rrank; 6010 ++m; 6011 } else if ((p >= fStart) && (p < fMax)) { 6012 /* Interior faces add new faces, edges, and vertex */ 6013 for (r = 0; r < 4; ++r, ++m) { 6014 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6015 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6016 remotePointsNew[m].rank = rrank; 6017 } 6018 for (r = 0; r < 4; ++r, ++m) { 6019 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6020 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 6021 remotePointsNew[m].rank = rrank; 6022 } 6023 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6024 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 6025 remotePointsNew[m].rank = rrank; 6026 ++m; 6027 } else if ((p >= fMax) && (p < fEnd)) { 6028 /* Hybrid faces add new faces and edges */ 6029 for (r = 0; r < 2; ++r, ++m) { 6030 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6031 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 6032 remotePointsNew[m].rank = rrank; 6033 } 6034 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 6035 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)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 6036 remotePointsNew[m].rank = rrank; 6037 ++m; 6038 } else if ((p >= cStart) && (p < cMax)) { 6039 /* Interior cells add new cells, faces, edges, and vertex */ 6040 for (r = 0; r < 8; ++r, ++m) { 6041 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6042 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6043 remotePointsNew[m].rank = rrank; 6044 } 6045 for (r = 0; r < 12; ++r, ++m) { 6046 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6047 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6048 remotePointsNew[m].rank = rrank; 6049 } 6050 for (r = 0; r < 6; ++r, ++m) { 6051 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6052 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; 6053 remotePointsNew[m].rank = rrank; 6054 } 6055 for (r = 0; r < 1; ++r, ++m) { 6056 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6057 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6058 remotePointsNew[m].rank = rrank; 6059 } 6060 } else if ((p >= cMax) && (p < cEnd)) { 6061 /* Hybrid cells add new cells, faces, and edges */ 6062 for (r = 0; r < 4; ++r, ++m) { 6063 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6064 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6065 remotePointsNew[m].rank = rrank; 6066 } 6067 for (r = 0; r < 4; ++r, ++m) { 6068 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6069 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6070 remotePointsNew[m].rank = rrank; 6071 } 6072 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 6073 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)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]); 6074 remotePointsNew[m].rank = rrank; 6075 ++m; 6076 } 6077 break; 6078 default: 6079 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6080 } 6081 } 6082 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6083 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6084 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6085 { 6086 PetscSFNode *rp, *rtmp; 6087 PetscInt *lp, *idx, *ltmp, i; 6088 6089 /* SF needs sorted leaves to correct calculate Gather */ 6090 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 6091 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 6092 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 6093 for (i = 0; i < numLeavesNew; ++i) { 6094 if ((localPointsNew[i] < pStartNew) || (localPointsNew[i] >= pEndNew)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local SF point %d (%d) not in [%d, %d)", localPointsNew[i], i, pStartNew, pEndNew); 6095 idx[i] = i; 6096 } 6097 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 6098 for (i = 0; i < numLeavesNew; ++i) { 6099 lp[i] = localPointsNew[idx[i]]; 6100 rp[i] = remotePointsNew[idx[i]]; 6101 } 6102 ltmp = localPointsNew; 6103 localPointsNew = lp; 6104 rtmp = remotePointsNew; 6105 remotePointsNew = rp; 6106 ierr = PetscFree(idx);CHKERRQ(ierr); 6107 ierr = PetscFree(ltmp);CHKERRQ(ierr); 6108 ierr = PetscFree(rtmp);CHKERRQ(ierr); 6109 } 6110 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6111 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6112 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6113 PetscFunctionReturn(0); 6114 } 6115 6116 #undef __FUNCT__ 6117 #define __FUNCT__ "CellRefinerCreateLabels" 6118 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6119 { 6120 PetscInt numLabels, l; 6121 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6122 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6123 PetscErrorCode ierr; 6124 6125 PetscFunctionBegin; 6126 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6127 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6128 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6129 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6130 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6131 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6132 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6133 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6134 switch (refiner) { 6135 case 0: break; 6136 case 7: 6137 case 8: 6138 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6139 case 3: 6140 case 4: 6141 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6142 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6143 } 6144 for (l = 0; l < numLabels; ++l) { 6145 DMLabel label, labelNew; 6146 const char *lname; 6147 PetscBool isDepth; 6148 IS valueIS; 6149 const PetscInt *values; 6150 PetscInt numValues, val; 6151 6152 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6153 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6154 if (isDepth) continue; 6155 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6156 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6157 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6158 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6159 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6160 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6161 for (val = 0; val < numValues; ++val) { 6162 IS pointIS; 6163 const PetscInt *points; 6164 PetscInt numPoints, n; 6165 6166 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6167 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6168 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6169 for (n = 0; n < numPoints; ++n) { 6170 const PetscInt p = points[n]; 6171 switch (refiner) { 6172 case 1: 6173 /* Simplicial 2D */ 6174 if ((p >= vStart) && (p < vEnd)) { 6175 /* Old vertices stay the same */ 6176 newp = vStartNew + (p - vStart); 6177 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6178 } else if ((p >= fStart) && (p < fEnd)) { 6179 /* Old faces add new faces and vertex */ 6180 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6181 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6182 for (r = 0; r < 2; ++r) { 6183 newp = fStartNew + (p - fStart)*2 + r; 6184 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6185 } 6186 } else if ((p >= cStart) && (p < cEnd)) { 6187 /* Old cells add new cells and interior faces */ 6188 for (r = 0; r < 4; ++r) { 6189 newp = cStartNew + (p - cStart)*4 + r; 6190 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6191 } 6192 for (r = 0; r < 3; ++r) { 6193 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6194 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6195 } 6196 } 6197 break; 6198 case 2: 6199 /* Hex 2D */ 6200 if ((p >= vStart) && (p < vEnd)) { 6201 /* Old vertices stay the same */ 6202 newp = vStartNew + (p - vStart); 6203 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6204 } else if ((p >= fStart) && (p < fEnd)) { 6205 /* Old faces add new faces and vertex */ 6206 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6207 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6208 for (r = 0; r < 2; ++r) { 6209 newp = fStartNew + (p - fStart)*2 + r; 6210 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6211 } 6212 } else if ((p >= cStart) && (p < cEnd)) { 6213 /* Old cells add new cells and interior faces and vertex */ 6214 for (r = 0; r < 4; ++r) { 6215 newp = cStartNew + (p - cStart)*4 + r; 6216 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6217 } 6218 for (r = 0; r < 4; ++r) { 6219 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6220 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6221 } 6222 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6223 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6224 } 6225 break; 6226 case 3: 6227 /* Hybrid simplicial 2D */ 6228 if ((p >= vStart) && (p < vEnd)) { 6229 /* Old vertices stay the same */ 6230 newp = vStartNew + (p - vStart); 6231 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6232 } else if ((p >= fStart) && (p < fMax)) { 6233 /* Old interior faces add new faces and vertex */ 6234 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6235 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6236 for (r = 0; r < 2; ++r) { 6237 newp = fStartNew + (p - fStart)*2 + r; 6238 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6239 } 6240 } else if ((p >= fMax) && (p < fEnd)) { 6241 /* Old hybrid faces stay the same */ 6242 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6243 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6244 } else if ((p >= cStart) && (p < cMax)) { 6245 /* Old interior cells add new cells and interior faces */ 6246 for (r = 0; r < 4; ++r) { 6247 newp = cStartNew + (p - cStart)*4 + r; 6248 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6249 } 6250 for (r = 0; r < 3; ++r) { 6251 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6252 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6253 } 6254 } else if ((p >= cMax) && (p < cEnd)) { 6255 /* Old hybrid cells add new cells and hybrid face */ 6256 for (r = 0; r < 2; ++r) { 6257 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6258 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6259 } 6260 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6261 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6262 } 6263 break; 6264 case 4: 6265 /* Hybrid Hex 2D */ 6266 if ((p >= vStart) && (p < vEnd)) { 6267 /* Old vertices stay the same */ 6268 newp = vStartNew + (p - vStart); 6269 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6270 } else if ((p >= fStart) && (p < fMax)) { 6271 /* Old interior faces add new faces and vertex */ 6272 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6273 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6274 for (r = 0; r < 2; ++r) { 6275 newp = fStartNew + (p - fStart)*2 + r; 6276 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6277 } 6278 } else if ((p >= fMax) && (p < fEnd)) { 6279 /* Old hybrid faces stay the same */ 6280 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6281 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6282 } else if ((p >= cStart) && (p < cMax)) { 6283 /* Old interior cells add new cells, interior faces, and vertex */ 6284 for (r = 0; r < 4; ++r) { 6285 newp = cStartNew + (p - cStart)*4 + r; 6286 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6287 } 6288 for (r = 0; r < 4; ++r) { 6289 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6290 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6291 } 6292 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6293 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6294 } else if ((p >= cMax) && (p < cEnd)) { 6295 /* Old hybrid cells add new cells and hybrid face */ 6296 for (r = 0; r < 2; ++r) { 6297 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6298 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6299 } 6300 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6301 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6302 } 6303 break; 6304 case 5: 6305 /* Simplicial 3D */ 6306 if ((p >= vStart) && (p < vEnd)) { 6307 /* Old vertices stay the same */ 6308 newp = vStartNew + (p - vStart); 6309 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6310 } else if ((p >= eStart) && (p < eEnd)) { 6311 /* Old edges add new edges and vertex */ 6312 for (r = 0; r < 2; ++r) { 6313 newp = eStartNew + (p - eStart)*2 + r; 6314 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6315 } 6316 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6317 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6318 } else if ((p >= fStart) && (p < fEnd)) { 6319 /* Old faces add new faces and edges */ 6320 for (r = 0; r < 4; ++r) { 6321 newp = fStartNew + (p - fStart)*4 + r; 6322 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6323 } 6324 for (r = 0; r < 3; ++r) { 6325 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6326 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6327 } 6328 } else if ((p >= cStart) && (p < cEnd)) { 6329 /* Old cells add new cells and interior faces and edges */ 6330 for (r = 0; r < 8; ++r) { 6331 newp = cStartNew + (p - cStart)*8 + r; 6332 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6333 } 6334 for (r = 0; r < 8; ++r) { 6335 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6336 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6337 } 6338 for (r = 0; r < 1; ++r) { 6339 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6340 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6341 } 6342 } 6343 break; 6344 case 7: 6345 /* Hybrid Simplicial 3D */ 6346 if ((p >= vStart) && (p < vEnd)) { 6347 /* Interior vertices stay the same */ 6348 newp = vStartNew + (p - vStart); 6349 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6350 } else if ((p >= eStart) && (p < eMax)) { 6351 /* Interior edges add new edges and vertex */ 6352 for (r = 0; r < 2; ++r) { 6353 newp = eStartNew + (p - eStart)*2 + r; 6354 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6355 } 6356 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6357 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6358 } else if ((p >= eMax) && (p < eEnd)) { 6359 /* Hybrid edges stay the same */ 6360 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6361 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6362 } else if ((p >= fStart) && (p < fMax)) { 6363 /* Interior faces add new faces and edges */ 6364 for (r = 0; r < 4; ++r) { 6365 newp = fStartNew + (p - fStart)*4 + r; 6366 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6367 } 6368 for (r = 0; r < 3; ++r) { 6369 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6370 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6371 } 6372 } else if ((p >= fMax) && (p < fEnd)) { 6373 /* Hybrid faces add new faces and edges */ 6374 for (r = 0; r < 2; ++r) { 6375 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6376 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6377 } 6378 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6379 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6380 } else if ((p >= cStart) && (p < cMax)) { 6381 /* Interior cells add new cells, faces, and edges */ 6382 for (r = 0; r < 8; ++r) { 6383 newp = cStartNew + (p - cStart)*8 + r; 6384 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6385 } 6386 for (r = 0; r < 8; ++r) { 6387 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6388 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6389 } 6390 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6391 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6392 } else if ((p >= cMax) && (p < cEnd)) { 6393 /* Hybrid cells add new cells and faces */ 6394 for (r = 0; r < 4; ++r) { 6395 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6396 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6397 } 6398 for (r = 0; r < 3; ++r) { 6399 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6400 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6401 } 6402 } 6403 break; 6404 case 6: 6405 /* Hex 3D */ 6406 if ((p >= vStart) && (p < vEnd)) { 6407 /* Old vertices stay the same */ 6408 newp = vStartNew + (p - vStart); 6409 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6410 } else if ((p >= eStart) && (p < eEnd)) { 6411 /* Old edges add new edges and vertex */ 6412 for (r = 0; r < 2; ++r) { 6413 newp = eStartNew + (p - eStart)*2 + r; 6414 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6415 } 6416 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6417 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6418 } else if ((p >= fStart) && (p < fEnd)) { 6419 /* Old faces add new faces, edges, and vertex */ 6420 for (r = 0; r < 4; ++r) { 6421 newp = fStartNew + (p - fStart)*4 + r; 6422 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6423 } 6424 for (r = 0; r < 4; ++r) { 6425 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6426 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6427 } 6428 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6429 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6430 } else if ((p >= cStart) && (p < cEnd)) { 6431 /* Old cells add new cells, faces, edges, and vertex */ 6432 for (r = 0; r < 8; ++r) { 6433 newp = cStartNew + (p - cStart)*8 + r; 6434 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6435 } 6436 for (r = 0; r < 12; ++r) { 6437 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6438 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6439 } 6440 for (r = 0; r < 6; ++r) { 6441 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6442 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6443 } 6444 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6445 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6446 } 6447 break; 6448 case 8: 6449 /* Hybrid Hex 3D */ 6450 if ((p >= vStart) && (p < vEnd)) { 6451 /* Interior vertices stay the same */ 6452 newp = vStartNew + (p - vStart); 6453 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6454 } else if ((p >= eStart) && (p < eMax)) { 6455 /* Interior edges add new edges and vertex */ 6456 for (r = 0; r < 2; ++r) { 6457 newp = eStartNew + (p - eStart)*2 + r; 6458 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6459 } 6460 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6461 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6462 } else if ((p >= eMax) && (p < eEnd)) { 6463 /* Hybrid edges stay the same */ 6464 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6465 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6466 } else if ((p >= fStart) && (p < fMax)) { 6467 /* Interior faces add new faces, edges, and vertex */ 6468 for (r = 0; r < 4; ++r) { 6469 newp = fStartNew + (p - fStart)*4 + r; 6470 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6471 } 6472 for (r = 0; r < 4; ++r) { 6473 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6474 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6475 } 6476 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6477 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6478 } else if ((p >= fMax) && (p < fEnd)) { 6479 /* Hybrid faces add new faces and edges */ 6480 for (r = 0; r < 2; ++r) { 6481 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6482 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6483 } 6484 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6485 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6486 } else if ((p >= cStart) && (p < cMax)) { 6487 /* Interior cells add new cells, faces, edges, and vertex */ 6488 for (r = 0; r < 8; ++r) { 6489 newp = cStartNew + (p - cStart)*8 + r; 6490 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6491 } 6492 for (r = 0; r < 12; ++r) { 6493 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6494 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6495 } 6496 for (r = 0; r < 6; ++r) { 6497 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6498 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6499 } 6500 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6501 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6502 } else if ((p >= cMax) && (p < cEnd)) { 6503 /* Hybrid cells add new cells, faces, and edges */ 6504 for (r = 0; r < 4; ++r) { 6505 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6506 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6507 } 6508 for (r = 0; r < 4; ++r) { 6509 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6511 } 6512 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6513 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6514 } 6515 break; 6516 default: 6517 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6518 } 6519 } 6520 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6521 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6522 } 6523 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6524 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6525 if (0) { 6526 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6527 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6528 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6529 } 6530 } 6531 PetscFunctionReturn(0); 6532 } 6533 6534 #undef __FUNCT__ 6535 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6536 /* This will only work for interpolated meshes */ 6537 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6538 { 6539 DM rdm; 6540 PetscInt *depthSize; 6541 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6542 PetscErrorCode ierr; 6543 6544 PetscFunctionBegin; 6545 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6546 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6547 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6548 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 6549 /* Calculate number of new points of each depth */ 6550 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6551 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6552 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6553 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6554 /* Step 1: Set chart */ 6555 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6556 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6557 /* Step 2: Set cone/support sizes */ 6558 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6559 /* Step 3: Setup refined DM */ 6560 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6561 /* Step 4: Set cones and supports */ 6562 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6563 /* Step 5: Stratify */ 6564 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6565 /* Step 6: Create pointSF */ 6566 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6567 /* Step 7: Set coordinates for vertices */ 6568 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6569 /* Step 8: Create labels */ 6570 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6571 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6572 6573 *dmRefined = rdm; 6574 PetscFunctionReturn(0); 6575 } 6576 6577 #undef __FUNCT__ 6578 #define __FUNCT__ "DMPlexCreateCoarsePointIS" 6579 /*@ 6580 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 6581 6582 Input Parameter: 6583 . dm - The coarse DM 6584 6585 Output Parameter: 6586 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 6587 6588 Level: developer 6589 6590 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 6591 @*/ 6592 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 6593 { 6594 CellRefiner cellRefiner; 6595 PetscInt *depthSize, *fpoints; 6596 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6597 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 6598 PetscErrorCode ierr; 6599 6600 PetscFunctionBegin; 6601 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6602 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6603 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6604 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 6605 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6606 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6607 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6608 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 6609 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 6610 switch (cellRefiner) { 6611 case 1: /* Simplicial 2D */ 6612 case 3: /* Hybrid simplicial 2D */ 6613 case 2: /* Hex 2D */ 6614 case 4: /* Hybrid Hex 2D */ 6615 case 5: /* Simplicial 3D */ 6616 case 7: /* Hybrid Simplicial 3D */ 6617 case 6: /* Hex 3D */ 6618 case 8: /* Hybrid Hex 3D */ 6619 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 6620 break; 6621 default: 6622 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 6623 } 6624 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 6625 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6626 PetscFunctionReturn(0); 6627 } 6628 6629 #undef __FUNCT__ 6630 #define __FUNCT__ "DMPlexSetRefinementUniform" 6631 /*@ 6632 DMPlexSetRefinementUniform - Set the flag for uniform refinement 6633 6634 Input Parameters: 6635 + dm - The DM 6636 - refinementUniform - The flag for uniform refinement 6637 6638 Level: developer 6639 6640 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6641 @*/ 6642 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6643 { 6644 DM_Plex *mesh = (DM_Plex*) dm->data; 6645 6646 PetscFunctionBegin; 6647 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6648 mesh->refinementUniform = refinementUniform; 6649 PetscFunctionReturn(0); 6650 } 6651 6652 #undef __FUNCT__ 6653 #define __FUNCT__ "DMPlexGetRefinementUniform" 6654 /*@ 6655 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 6656 6657 Input Parameter: 6658 . dm - The DM 6659 6660 Output Parameter: 6661 . refinementUniform - The flag for uniform refinement 6662 6663 Level: developer 6664 6665 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6666 @*/ 6667 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6668 { 6669 DM_Plex *mesh = (DM_Plex*) dm->data; 6670 6671 PetscFunctionBegin; 6672 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6673 PetscValidPointer(refinementUniform, 2); 6674 *refinementUniform = mesh->refinementUniform; 6675 PetscFunctionReturn(0); 6676 } 6677 6678 #undef __FUNCT__ 6679 #define __FUNCT__ "DMPlexSetRefinementLimit" 6680 /*@ 6681 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 6682 6683 Input Parameters: 6684 + dm - The DM 6685 - refinementLimit - The maximum cell volume in the refined mesh 6686 6687 Level: developer 6688 6689 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6690 @*/ 6691 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6692 { 6693 DM_Plex *mesh = (DM_Plex*) dm->data; 6694 6695 PetscFunctionBegin; 6696 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6697 mesh->refinementLimit = refinementLimit; 6698 PetscFunctionReturn(0); 6699 } 6700 6701 #undef __FUNCT__ 6702 #define __FUNCT__ "DMPlexGetRefinementLimit" 6703 /*@ 6704 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 6705 6706 Input Parameter: 6707 . dm - The DM 6708 6709 Output Parameter: 6710 . refinementLimit - The maximum cell volume in the refined mesh 6711 6712 Level: developer 6713 6714 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6715 @*/ 6716 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6717 { 6718 DM_Plex *mesh = (DM_Plex*) dm->data; 6719 6720 PetscFunctionBegin; 6721 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6722 PetscValidPointer(refinementLimit, 2); 6723 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6724 *refinementLimit = mesh->refinementLimit; 6725 PetscFunctionReturn(0); 6726 } 6727 6728 #undef __FUNCT__ 6729 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6730 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6731 { 6732 PetscInt dim, cStart, cEnd, coneSize, cMax; 6733 PetscErrorCode ierr; 6734 6735 PetscFunctionBegin; 6736 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6737 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6738 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 6739 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6740 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6741 switch (dim) { 6742 case 2: 6743 switch (coneSize) { 6744 case 3: 6745 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 6746 else *cellRefiner = 1; /* Triangular */ 6747 break; 6748 case 4: 6749 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 6750 else *cellRefiner = 2; /* Quadrilateral */ 6751 break; 6752 default: 6753 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6754 } 6755 break; 6756 case 3: 6757 switch (coneSize) { 6758 case 4: 6759 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 6760 else *cellRefiner = 5; /* Tetrahedral */ 6761 break; 6762 case 6: 6763 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 6764 else *cellRefiner = 6; /* hexahedral */ 6765 break; 6766 default: 6767 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6768 } 6769 break; 6770 default: 6771 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6772 } 6773 PetscFunctionReturn(0); 6774 } 6775