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