1 #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2 #include <petscsf.h> 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "GetDepthStart_Private" 6 PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 7 { 8 PetscFunctionBegin; 9 if (cStart) *cStart = 0; 10 if (vStart) *vStart = depthSize[depth]; 11 if (fStart) *fStart = depthSize[depth] + depthSize[0]; 12 if (eStart) *eStart = depthSize[depth] + depthSize[0] + depthSize[depth-1]; 13 PetscFunctionReturn(0); 14 } 15 16 #undef __FUNCT__ 17 #define __FUNCT__ "GetDepthEnd_Private" 18 PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 19 { 20 PetscFunctionBegin; 21 if (cEnd) *cEnd = depthSize[depth]; 22 if (vEnd) *vEnd = depthSize[depth] + depthSize[0]; 23 if (fEnd) *fEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1]; 24 if (eEnd) *eEnd = depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 25 PetscFunctionReturn(0); 26 } 27 28 #undef __FUNCT__ 29 #define __FUNCT__ "CellRefinerGetAffineTransforms_Internal" 30 /* Gets the affine map from the original cell to each subcell */ 31 PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 32 { 33 PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ; 34 PetscInt dim, s; 35 PetscErrorCode ierr; 36 37 PetscFunctionBegin; 38 switch (refiner) { 39 case 0: break; 40 case 1: 41 dim = 2; 42 if (numSubcells) *numSubcells = 4; 43 if (v0) { 44 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 45 /* A */ 46 v[0+0] = -1.0; v[0+1] = -1.0; 47 j[0+0] = 0.5; j[0+1] = 0.0; 48 j[0+2] = 0.0; j[0+3] = 0.5; 49 /* B */ 50 v[2+0] = 0.0; v[2+1] = -1.0; 51 j[4+0] = 0.5; j[4+1] = 0.0; 52 j[4+2] = 0.0; j[4+3] = 0.5; 53 /* C */ 54 v[4+0] = -1.0; v[4+1] = 0.0; 55 j[8+0] = 0.5; j[8+1] = 0.0; 56 j[8+2] = 0.0; j[8+3] = 0.5; 57 /* D */ 58 v[6+0] = 0.0; v[6+1] = -1.0; 59 j[12+0] = 0.0; j[12+1] = -0.5; 60 j[12+2] = 0.5; j[12+3] = 0.5; 61 for (s = 0; s < 4; ++s) { 62 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 63 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 64 } 65 } 66 break; 67 default: 68 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 69 } 70 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 71 PetscFunctionReturn(0); 72 } 73 74 #undef __FUNCT__ 75 #define __FUNCT__ "CellRefinerRestoreAffineTransforms_Internal" 76 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 77 { 78 PetscErrorCode ierr; 79 80 PetscFunctionBegin; 81 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 82 PetscFunctionReturn(0); 83 } 84 85 #undef __FUNCT__ 86 #define __FUNCT__ "CellRefinerGetSizes" 87 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 88 { 89 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 90 PetscErrorCode ierr; 91 92 PetscFunctionBegin; 93 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 94 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 95 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 96 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 97 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 98 switch (refiner) { 99 case 0: 100 break; 101 case 1: 102 /* Simplicial 2D */ 103 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 104 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 105 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 106 break; 107 case 3: 108 /* Hybrid Simplicial 2D */ 109 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 110 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 111 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 112 depthSize[1] = 2*(fMax - fStart) + 3*(cMax - cStart) + (fEnd - fMax) + (cEnd - cMax); /* Every interior face is split into 2 faces, 3 faces are added for each interior cell, and one in each hybrid cell */ 113 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 114 break; 115 case 2: 116 /* Hex 2D */ 117 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 118 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 119 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 120 break; 121 case 4: 122 /* Hybrid Hex 2D */ 123 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 124 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 125 /* Quadrilateral */ 126 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 127 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 128 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 129 /* Segment Prisms */ 130 depthSize[0] += 0; /* No hybrid vertices */ 131 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 132 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 133 break; 134 case 5: 135 /* Simplicial 3D */ 136 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 137 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 */ 138 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 139 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 140 break; 141 case 7: 142 /* Hybrid Simplicial 3D */ 143 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 144 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 145 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 146 /* Tetrahedra */ 147 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 148 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 */ 149 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 150 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 151 /* Triangular Prisms */ 152 depthSize[0] += 0; /* No hybrid vertices */ 153 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 154 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 155 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 156 break; 157 case 6: 158 /* Hex 3D */ 159 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 160 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 */ 161 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 162 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 163 break; 164 case 8: 165 /* Hybrid Hex 3D */ 166 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 167 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 168 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 169 /* Hexahedra */ 170 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 171 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 */ 172 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 173 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 174 /* Quadrilateral Prisms */ 175 depthSize[0] += 0; /* No hybrid vertices */ 176 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 177 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 178 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 179 break; 180 default: 181 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 182 } 183 PetscFunctionReturn(0); 184 } 185 186 /* Return triangle edge for orientation o, if it is r for o == 0 */ 187 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 188 return (o < 0 ? 2-(o+r) : o+r)%3; 189 } 190 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 191 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 192 } 193 194 /* Return triangle subface for orientation o, if it is r for o == 0 */ 195 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 196 return (o < 0 ? 3-(o+r) : o+r)%3; 197 } 198 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 199 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 200 } 201 202 /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */ 203 PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) { 204 return (o < 0 ? 1-(o+r) : o+r)%3; 205 } 206 PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) { 207 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 208 } 209 210 211 /* Return quad edge for orientation o, if it is r for o == 0 */ 212 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 213 return (o < 0 ? 3-(o+r) : o+r)%4; 214 } 215 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 216 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 217 } 218 219 /* Return quad subface for orientation o, if it is r for o == 0 */ 220 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 221 return (o < 0 ? 4-(o+r) : o+r)%4; 222 } 223 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 224 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 225 } 226 227 #undef __FUNCT__ 228 #define __FUNCT__ "CellRefinerSetConeSizes" 229 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 230 { 231 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 232 PetscErrorCode ierr; 233 234 PetscFunctionBegin; 235 if (!refiner) PetscFunctionReturn(0); 236 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 237 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 238 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 239 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 240 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 241 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 242 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 243 switch (refiner) { 244 case 1: 245 /* Simplicial 2D */ 246 /* All cells have 3 faces */ 247 for (c = cStart; c < cEnd; ++c) { 248 for (r = 0; r < 4; ++r) { 249 const PetscInt newp = (c - cStart)*4 + r; 250 251 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 252 } 253 } 254 /* Split faces have 2 vertices and the same cells as the parent */ 255 for (f = fStart; f < fEnd; ++f) { 256 for (r = 0; r < 2; ++r) { 257 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 258 PetscInt size; 259 260 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 261 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 262 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 263 } 264 } 265 /* Interior faces have 2 vertices and 2 cells */ 266 for (c = cStart; c < cEnd; ++c) { 267 for (r = 0; r < 3; ++r) { 268 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 269 270 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 271 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 272 } 273 } 274 /* Old vertices have identical supports */ 275 for (v = vStart; v < vEnd; ++v) { 276 const PetscInt newp = vStartNew + (v - vStart); 277 PetscInt size; 278 279 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 280 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 281 } 282 /* Face vertices have 2 + cells*2 supports */ 283 for (f = fStart; f < fEnd; ++f) { 284 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 285 PetscInt size; 286 287 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 288 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 289 } 290 break; 291 case 2: 292 /* Hex 2D */ 293 /* All cells have 4 faces */ 294 for (c = cStart; c < cEnd; ++c) { 295 for (r = 0; r < 4; ++r) { 296 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 297 298 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 299 } 300 } 301 /* Split faces have 2 vertices and the same cells as the parent */ 302 for (f = fStart; f < fEnd; ++f) { 303 for (r = 0; r < 2; ++r) { 304 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 305 PetscInt size; 306 307 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 308 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 309 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 310 } 311 } 312 /* Interior faces have 2 vertices and 2 cells */ 313 for (c = cStart; c < cEnd; ++c) { 314 for (r = 0; r < 4; ++r) { 315 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 316 317 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 318 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 319 } 320 } 321 /* Old vertices have identical supports */ 322 for (v = vStart; v < vEnd; ++v) { 323 const PetscInt newp = vStartNew + (v - vStart); 324 PetscInt size; 325 326 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 327 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 328 } 329 /* Face vertices have 2 + cells supports */ 330 for (f = fStart; f < fEnd; ++f) { 331 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 332 PetscInt size; 333 334 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 335 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 336 } 337 /* Cell vertices have 4 supports */ 338 for (c = cStart; c < cEnd; ++c) { 339 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 340 341 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 342 } 343 break; 344 case 3: 345 /* Hybrid Simplicial 2D */ 346 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 347 cMax = PetscMin(cEnd, cMax); 348 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 349 fMax = PetscMin(fEnd, fMax); 350 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 351 /* Interior cells have 3 faces */ 352 for (c = cStart; c < cMax; ++c) { 353 for (r = 0; r < 4; ++r) { 354 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 355 356 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 357 } 358 } 359 /* Hybrid cells have 4 faces */ 360 for (c = cMax; c < cEnd; ++c) { 361 for (r = 0; r < 2; ++r) { 362 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 363 364 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 365 } 366 } 367 /* Interior split faces have 2 vertices and the same cells as the parent */ 368 for (f = fStart; f < fMax; ++f) { 369 for (r = 0; r < 2; ++r) { 370 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 371 PetscInt size; 372 373 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 374 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 375 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 376 } 377 } 378 /* Interior cell faces have 2 vertices and 2 cells */ 379 for (c = cStart; c < cMax; ++c) { 380 for (r = 0; r < 3; ++r) { 381 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 382 383 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 384 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 385 } 386 } 387 /* Hybrid faces have 2 vertices and the same cells */ 388 for (f = fMax; f < fEnd; ++f) { 389 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 390 PetscInt size; 391 392 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 393 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 394 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 395 } 396 /* Hybrid cell faces have 2 vertices and 2 cells */ 397 for (c = cMax; c < cEnd; ++c) { 398 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 399 400 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 401 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 402 } 403 /* Old vertices have identical supports */ 404 for (v = vStart; v < vEnd; ++v) { 405 const PetscInt newp = vStartNew + (v - vStart); 406 PetscInt size; 407 408 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 409 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 410 } 411 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 412 for (f = fStart; f < fMax; ++f) { 413 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 414 const PetscInt *support; 415 PetscInt size, newSize = 2, s; 416 417 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 418 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 419 for (s = 0; s < size; ++s) { 420 if (support[s] >= cMax) newSize += 1; 421 else newSize += 2; 422 } 423 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 424 } 425 break; 426 case 4: 427 /* Hybrid Hex 2D */ 428 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 429 cMax = PetscMin(cEnd, cMax); 430 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 431 fMax = PetscMin(fEnd, fMax); 432 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 433 /* Interior cells have 4 faces */ 434 for (c = cStart; c < cMax; ++c) { 435 for (r = 0; r < 4; ++r) { 436 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 437 438 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 439 } 440 } 441 /* Hybrid cells have 4 faces */ 442 for (c = cMax; c < cEnd; ++c) { 443 for (r = 0; r < 2; ++r) { 444 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 445 446 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 447 } 448 } 449 /* Interior split faces have 2 vertices and the same cells as the parent */ 450 for (f = fStart; f < fMax; ++f) { 451 for (r = 0; r < 2; ++r) { 452 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 453 PetscInt size; 454 455 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 456 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 457 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 458 } 459 } 460 /* Interior cell faces have 2 vertices and 2 cells */ 461 for (c = cStart; c < cMax; ++c) { 462 for (r = 0; r < 4; ++r) { 463 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 464 465 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 466 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 467 } 468 } 469 /* Hybrid faces have 2 vertices and the same cells */ 470 for (f = fMax; f < fEnd; ++f) { 471 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 472 PetscInt size; 473 474 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 475 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 476 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 477 } 478 /* Hybrid cell faces have 2 vertices and 2 cells */ 479 for (c = cMax; c < cEnd; ++c) { 480 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 481 482 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 483 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 484 } 485 /* Old vertices have identical supports */ 486 for (v = vStart; v < vEnd; ++v) { 487 const PetscInt newp = vStartNew + (v - vStart); 488 PetscInt size; 489 490 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 491 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 492 } 493 /* Face vertices have 2 + cells supports */ 494 for (f = fStart; f < fMax; ++f) { 495 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 496 PetscInt size; 497 498 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 499 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 500 } 501 /* Cell vertices have 4 supports */ 502 for (c = cStart; c < cMax; ++c) { 503 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 504 505 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 506 } 507 break; 508 case 5: 509 /* Simplicial 3D */ 510 /* All cells have 4 faces */ 511 for (c = cStart; c < cEnd; ++c) { 512 for (r = 0; r < 8; ++r) { 513 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 514 515 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 516 } 517 } 518 /* Split faces have 3 edges and the same cells as the parent */ 519 for (f = fStart; f < fEnd; ++f) { 520 for (r = 0; r < 4; ++r) { 521 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 522 PetscInt size; 523 524 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 525 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 526 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 527 } 528 } 529 /* Interior cell faces have 3 edges and 2 cells */ 530 for (c = cStart; c < cEnd; ++c) { 531 for (r = 0; r < 8; ++r) { 532 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 533 534 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 535 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 536 } 537 } 538 /* Split edges have 2 vertices and the same faces */ 539 for (e = eStart; e < eEnd; ++e) { 540 for (r = 0; r < 2; ++r) { 541 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 542 PetscInt size; 543 544 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 545 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 546 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 547 } 548 } 549 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 550 for (f = fStart; f < fEnd; ++f) { 551 for (r = 0; r < 3; ++r) { 552 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 553 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 554 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 555 556 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 557 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 558 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 559 for (s = 0; s < supportSize; ++s) { 560 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 561 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 562 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 563 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 564 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 565 er = GetTetSomethingInverse_Static(ornt[c], r); 566 if (er == eint[c]) { 567 intFaces += 1; 568 } else { 569 intFaces += 2; 570 } 571 } 572 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 573 } 574 } 575 /* Interior cell edges have 2 vertices and 4 faces */ 576 for (c = cStart; c < cEnd; ++c) { 577 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 578 579 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 580 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 581 } 582 /* Old vertices have identical supports */ 583 for (v = vStart; v < vEnd; ++v) { 584 const PetscInt newp = vStartNew + (v - vStart); 585 PetscInt size; 586 587 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 588 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 589 } 590 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 591 for (e = eStart; e < eEnd; ++e) { 592 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 593 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 594 595 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 596 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 597 for (s = 0; s < starSize*2; s += 2) { 598 const PetscInt *cone, *ornt; 599 PetscInt e01, e23; 600 601 if ((star[s] >= cStart) && (star[s] < cEnd)) { 602 /* Check edge 0-1 */ 603 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 604 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 605 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 606 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 607 /* Check edge 2-3 */ 608 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 609 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 610 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 611 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 612 if ((e01 == e) || (e23 == e)) ++cellSize; 613 } 614 } 615 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 616 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 617 } 618 break; 619 case 7: 620 /* Hybrid Simplicial 3D */ 621 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 622 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 623 /* Interior cells have 4 faces */ 624 for (c = cStart; c < cMax; ++c) { 625 for (r = 0; r < 8; ++r) { 626 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 627 628 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 629 } 630 } 631 /* Hybrid cells have 5 faces */ 632 for (c = cMax; c < cEnd; ++c) { 633 for (r = 0; r < 4; ++r) { 634 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 635 636 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 637 } 638 } 639 /* Interior split faces have 3 edges and the same cells as the parent */ 640 for (f = fStart; f < fMax; ++f) { 641 for (r = 0; r < 4; ++r) { 642 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 643 PetscInt size; 644 645 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 646 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 647 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 648 } 649 } 650 /* Interior cell faces have 3 edges and 2 cells */ 651 for (c = cStart; c < cMax; ++c) { 652 for (r = 0; r < 8; ++r) { 653 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 654 655 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 656 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 657 } 658 } 659 /* Hybrid split faces have 4 edges and the same cells as the parent */ 660 for (f = fMax; f < fEnd; ++f) { 661 for (r = 0; r < 2; ++r) { 662 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 663 PetscInt size; 664 665 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 666 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 667 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 668 } 669 } 670 /* Hybrid cells faces have 4 edges and 2 cells */ 671 for (c = cMax; c < cEnd; ++c) { 672 for (r = 0; r < 3; ++r) { 673 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 674 675 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 676 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 677 } 678 } 679 /* Interior split edges have 2 vertices and the same faces */ 680 for (e = eStart; e < eMax; ++e) { 681 for (r = 0; r < 2; ++r) { 682 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 683 PetscInt size; 684 685 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 686 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 687 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 688 } 689 } 690 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 691 for (f = fStart; f < fMax; ++f) { 692 for (r = 0; r < 3; ++r) { 693 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 694 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 695 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 696 697 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 698 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 699 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 700 for (s = 0; s < supportSize; ++s) { 701 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 702 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 703 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 704 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 705 if (support[s] < cMax) { 706 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 707 er = GetTetSomethingInverse_Static(ornt[c], r); 708 if (er == eint[c]) { 709 intFaces += 1; 710 } else { 711 intFaces += 2; 712 } 713 } else { 714 intFaces += 1; 715 } 716 } 717 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 718 } 719 } 720 /* Interior cell edges have 2 vertices and 4 faces */ 721 for (c = cStart; c < cMax; ++c) { 722 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 723 724 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 725 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 726 } 727 /* Hybrid edges have 2 vertices and the same faces */ 728 for (e = eMax; e < eEnd; ++e) { 729 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 730 PetscInt size; 731 732 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 733 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 734 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 735 } 736 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 737 for (f = fMax; f < fEnd; ++f) { 738 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 739 PetscInt size; 740 741 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 742 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 743 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 744 } 745 /* Interior vertices have identical supports */ 746 for (v = vStart; v < vEnd; ++v) { 747 const PetscInt newp = vStartNew + (v - vStart); 748 PetscInt size; 749 750 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 751 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 752 } 753 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 754 for (e = eStart; e < eMax; ++e) { 755 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 756 const PetscInt *support; 757 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 758 759 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 760 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 761 for (s = 0; s < size; ++s) { 762 if (support[s] < fMax) faceSize += 2; 763 else faceSize += 1; 764 } 765 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 766 for (s = 0; s < starSize*2; s += 2) { 767 const PetscInt *cone, *ornt; 768 PetscInt e01, e23; 769 770 if ((star[s] >= cStart) && (star[s] < cMax)) { 771 /* Check edge 0-1 */ 772 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 773 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 774 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 775 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 776 /* Check edge 2-3 */ 777 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 778 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 779 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 780 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 781 if ((e01 == e) || (e23 == e)) ++cellSize; 782 } 783 } 784 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 785 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 786 } 787 break; 788 case 6: 789 /* Hex 3D */ 790 /* All cells have 6 faces */ 791 for (c = cStart; c < cEnd; ++c) { 792 for (r = 0; r < 8; ++r) { 793 const PetscInt newp = (c - cStart)*8 + r; 794 795 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 796 } 797 } 798 /* Split faces have 4 edges and the same cells as the parent */ 799 for (f = fStart; f < fEnd; ++f) { 800 for (r = 0; r < 4; ++r) { 801 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 802 PetscInt size; 803 804 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 805 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 806 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 807 } 808 } 809 /* Interior faces have 4 edges and 2 cells */ 810 for (c = cStart; c < cEnd; ++c) { 811 for (r = 0; r < 12; ++r) { 812 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 813 814 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 815 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 816 } 817 } 818 /* Split edges have 2 vertices and the same faces as the parent */ 819 for (e = eStart; e < eEnd; ++e) { 820 for (r = 0; r < 2; ++r) { 821 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 822 PetscInt size; 823 824 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 825 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 826 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 827 } 828 } 829 /* Face edges have 2 vertices and 2+cells faces */ 830 for (f = fStart; f < fEnd; ++f) { 831 for (r = 0; r < 4; ++r) { 832 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 833 PetscInt size; 834 835 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 836 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 837 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 838 } 839 } 840 /* Cell edges have 2 vertices and 4 faces */ 841 for (c = cStart; c < cEnd; ++c) { 842 for (r = 0; r < 6; ++r) { 843 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 844 845 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 846 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 847 } 848 } 849 /* Old vertices have identical supports */ 850 for (v = vStart; v < vEnd; ++v) { 851 const PetscInt newp = vStartNew + (v - vStart); 852 PetscInt size; 853 854 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 855 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 856 } 857 /* Edge vertices have 2 + faces supports */ 858 for (e = eStart; e < eEnd; ++e) { 859 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 860 PetscInt size; 861 862 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 863 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 864 } 865 /* Face vertices have 4 + cells supports */ 866 for (f = fStart; f < fEnd; ++f) { 867 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 868 PetscInt size; 869 870 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 871 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 872 } 873 /* Cell vertices have 6 supports */ 874 for (c = cStart; c < cEnd; ++c) { 875 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 876 877 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 878 } 879 break; 880 case 8: 881 /* Hybrid Hex 3D */ 882 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 883 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 884 /* Interior cells have 6 faces */ 885 for (c = cStart; c < cMax; ++c) { 886 for (r = 0; r < 8; ++r) { 887 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 888 889 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 890 } 891 } 892 /* Hybrid cells have 6 faces */ 893 for (c = cMax; c < cEnd; ++c) { 894 for (r = 0; r < 4; ++r) { 895 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 896 897 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 898 } 899 } 900 /* Interior split faces have 4 edges and the same cells as the parent */ 901 for (f = fStart; f < fMax; ++f) { 902 for (r = 0; r < 4; ++r) { 903 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 904 PetscInt size; 905 906 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 907 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 908 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 909 } 910 } 911 /* Interior cell faces have 4 edges and 2 cells */ 912 for (c = cStart; c < cMax; ++c) { 913 for (r = 0; r < 12; ++r) { 914 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 915 916 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 917 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 918 } 919 } 920 /* Hybrid split faces have 4 edges and the same cells as the parent */ 921 for (f = fMax; f < fEnd; ++f) { 922 for (r = 0; r < 2; ++r) { 923 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 924 PetscInt size; 925 926 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 927 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 928 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 929 } 930 } 931 /* Hybrid cells faces have 4 edges and 2 cells */ 932 for (c = cMax; c < cEnd; ++c) { 933 for (r = 0; r < 4; ++r) { 934 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 935 936 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 937 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 938 } 939 } 940 /* Interior split edges have 2 vertices and the same faces as the parent */ 941 for (e = eStart; e < eMax; ++e) { 942 for (r = 0; r < 2; ++r) { 943 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 944 PetscInt size; 945 946 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 947 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 948 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 949 } 950 } 951 /* Interior face edges have 2 vertices and 2+cells faces */ 952 for (f = fStart; f < fMax; ++f) { 953 for (r = 0; r < 4; ++r) { 954 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 955 PetscInt size; 956 957 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 958 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 959 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 960 } 961 } 962 /* Interior cell edges have 2 vertices and 4 faces */ 963 for (c = cStart; c < cMax; ++c) { 964 for (r = 0; r < 6; ++r) { 965 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 966 967 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 968 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 969 } 970 } 971 /* Hybrid edges have 2 vertices and the same faces */ 972 for (e = eMax; e < eEnd; ++e) { 973 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 974 PetscInt size; 975 976 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 977 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 978 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 979 } 980 /* Hybrid face edges have 2 vertices and 2+cells faces */ 981 for (f = fMax; f < fEnd; ++f) { 982 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 983 PetscInt size; 984 985 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 986 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 987 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 988 } 989 /* Hybrid cell edges have 2 vertices and 4 faces */ 990 for (c = cMax; c < cEnd; ++c) { 991 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 992 993 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 994 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 995 } 996 /* Interior vertices have identical supports */ 997 for (v = vStart; v < vEnd; ++v) { 998 const PetscInt newp = vStartNew + (v - vStart); 999 PetscInt size; 1000 1001 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1002 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1003 } 1004 /* Interior edge vertices have 2 + faces supports */ 1005 for (e = eStart; e < eMax; ++e) { 1006 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1007 PetscInt size; 1008 1009 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1010 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1011 } 1012 /* Interior face vertices have 4 + cells supports */ 1013 for (f = fStart; f < fMax; ++f) { 1014 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1015 PetscInt size; 1016 1017 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1018 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1019 } 1020 /* Interior cell vertices have 6 supports */ 1021 for (c = cStart; c < cMax; ++c) { 1022 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1023 1024 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1025 } 1026 break; 1027 default: 1028 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1029 } 1030 PetscFunctionReturn(0); 1031 } 1032 1033 #undef __FUNCT__ 1034 #define __FUNCT__ "CellRefinerSetCones" 1035 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1036 { 1037 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1038 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1039 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1040 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 1041 PetscErrorCode ierr; 1042 1043 PetscFunctionBegin; 1044 if (!refiner) PetscFunctionReturn(0); 1045 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1046 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1047 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1048 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1049 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1050 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1051 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1052 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1053 switch (refiner) { 1054 case 1: 1055 /* Simplicial 2D */ 1056 /* 1057 2 1058 |\ 1059 | \ 1060 | \ 1061 | \ 1062 | C \ 1063 | \ 1064 | \ 1065 2---1---1 1066 |\ D / \ 1067 | 2 0 \ 1068 |A \ / B \ 1069 0---0-------1 1070 */ 1071 /* All cells have 3 faces */ 1072 for (c = cStart; c < cEnd; ++c) { 1073 const PetscInt newp = cStartNew + (c - cStart)*4; 1074 const PetscInt *cone, *ornt; 1075 PetscInt coneNew[3], orntNew[3]; 1076 1077 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1078 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1079 /* A triangle */ 1080 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1081 orntNew[0] = ornt[0]; 1082 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1083 orntNew[1] = -2; 1084 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1085 orntNew[2] = ornt[2]; 1086 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1087 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1088 #if 1 1089 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); 1090 for (p = 0; p < 3; ++p) { 1091 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); 1092 } 1093 #endif 1094 /* B triangle */ 1095 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1096 orntNew[0] = ornt[0]; 1097 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1098 orntNew[1] = ornt[1]; 1099 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1100 orntNew[2] = -2; 1101 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1102 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1103 #if 1 1104 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); 1105 for (p = 0; p < 3; ++p) { 1106 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); 1107 } 1108 #endif 1109 /* C triangle */ 1110 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1111 orntNew[0] = -2; 1112 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1113 orntNew[1] = ornt[1]; 1114 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1115 orntNew[2] = ornt[2]; 1116 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1117 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1118 #if 1 1119 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); 1120 for (p = 0; p < 3; ++p) { 1121 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); 1122 } 1123 #endif 1124 /* D triangle */ 1125 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1126 orntNew[0] = 0; 1127 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1128 orntNew[1] = 0; 1129 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1130 orntNew[2] = 0; 1131 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1132 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1133 #if 1 1134 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); 1135 for (p = 0; p < 3; ++p) { 1136 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); 1137 } 1138 #endif 1139 } 1140 /* Split faces have 2 vertices and the same cells as the parent */ 1141 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1142 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1143 for (f = fStart; f < fEnd; ++f) { 1144 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1145 1146 for (r = 0; r < 2; ++r) { 1147 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1148 const PetscInt *cone, *ornt, *support; 1149 PetscInt coneNew[2], coneSize, c, supportSize, s; 1150 1151 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1152 coneNew[0] = vStartNew + (cone[0] - vStart); 1153 coneNew[1] = vStartNew + (cone[1] - vStart); 1154 coneNew[(r+1)%2] = newv; 1155 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1156 #if 1 1157 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1158 for (p = 0; p < 2; ++p) { 1159 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); 1160 } 1161 #endif 1162 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1163 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1164 for (s = 0; s < supportSize; ++s) { 1165 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1166 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1167 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1168 for (c = 0; c < coneSize; ++c) { 1169 if (cone[c] == f) break; 1170 } 1171 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1172 } 1173 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1174 #if 1 1175 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1176 for (p = 0; p < supportSize; ++p) { 1177 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); 1178 } 1179 #endif 1180 } 1181 } 1182 /* Interior faces have 2 vertices and 2 cells */ 1183 for (c = cStart; c < cEnd; ++c) { 1184 const PetscInt *cone; 1185 1186 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1187 for (r = 0; r < 3; ++r) { 1188 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1189 PetscInt coneNew[2]; 1190 PetscInt supportNew[2]; 1191 1192 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1193 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1194 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1195 #if 1 1196 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1197 for (p = 0; p < 2; ++p) { 1198 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); 1199 } 1200 #endif 1201 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1202 supportNew[1] = (c - cStart)*4 + 3; 1203 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1204 #if 1 1205 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1206 for (p = 0; p < 2; ++p) { 1207 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); 1208 } 1209 #endif 1210 } 1211 } 1212 /* Old vertices have identical supports */ 1213 for (v = vStart; v < vEnd; ++v) { 1214 const PetscInt newp = vStartNew + (v - vStart); 1215 const PetscInt *support, *cone; 1216 PetscInt size, s; 1217 1218 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1219 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1220 for (s = 0; s < size; ++s) { 1221 PetscInt r = 0; 1222 1223 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1224 if (cone[1] == v) r = 1; 1225 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1226 } 1227 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1228 #if 1 1229 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1230 for (p = 0; p < size; ++p) { 1231 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); 1232 } 1233 #endif 1234 } 1235 /* Face vertices have 2 + cells*2 supports */ 1236 for (f = fStart; f < fEnd; ++f) { 1237 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1238 const PetscInt *cone, *support; 1239 PetscInt size, s; 1240 1241 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1242 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1243 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1244 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1245 for (s = 0; s < size; ++s) { 1246 PetscInt r = 0; 1247 1248 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1249 if (cone[1] == f) r = 1; 1250 else if (cone[2] == f) r = 2; 1251 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1252 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1253 } 1254 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1255 #if 1 1256 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1257 for (p = 0; p < 2+size*2; ++p) { 1258 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); 1259 } 1260 #endif 1261 } 1262 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1263 break; 1264 case 2: 1265 /* Hex 2D */ 1266 /* 1267 3---------2---------2 1268 | | | 1269 | D 2 C | 1270 | | | 1271 3----3----0----1----1 1272 | | | 1273 | A 0 B | 1274 | | | 1275 0---------0---------1 1276 */ 1277 /* All cells have 4 faces */ 1278 for (c = cStart; c < cEnd; ++c) { 1279 const PetscInt newp = (c - cStart)*4; 1280 const PetscInt *cone, *ornt; 1281 PetscInt coneNew[4], orntNew[4]; 1282 1283 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1284 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1285 /* A quad */ 1286 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1287 orntNew[0] = ornt[0]; 1288 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1289 orntNew[1] = 0; 1290 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1291 orntNew[2] = -2; 1292 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1293 orntNew[3] = ornt[3]; 1294 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1295 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1296 #if 1 1297 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); 1298 for (p = 0; p < 4; ++p) { 1299 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); 1300 } 1301 #endif 1302 /* B quad */ 1303 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1304 orntNew[0] = ornt[0]; 1305 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1306 orntNew[1] = ornt[1]; 1307 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1308 orntNew[2] = 0; 1309 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1310 orntNew[3] = -2; 1311 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1312 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1313 #if 1 1314 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); 1315 for (p = 0; p < 4; ++p) { 1316 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); 1317 } 1318 #endif 1319 /* C quad */ 1320 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1321 orntNew[0] = -2; 1322 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1323 orntNew[1] = ornt[1]; 1324 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1325 orntNew[2] = ornt[2]; 1326 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1327 orntNew[3] = 0; 1328 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1329 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1330 #if 1 1331 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); 1332 for (p = 0; p < 4; ++p) { 1333 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); 1334 } 1335 #endif 1336 /* D quad */ 1337 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1338 orntNew[0] = 0; 1339 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1340 orntNew[1] = -2; 1341 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1342 orntNew[2] = ornt[2]; 1343 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1344 orntNew[3] = ornt[3]; 1345 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1346 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1347 #if 1 1348 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); 1349 for (p = 0; p < 4; ++p) { 1350 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); 1351 } 1352 #endif 1353 } 1354 /* Split faces have 2 vertices and the same cells as the parent */ 1355 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1356 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1357 for (f = fStart; f < fEnd; ++f) { 1358 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1359 1360 for (r = 0; r < 2; ++r) { 1361 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1362 const PetscInt *cone, *ornt, *support; 1363 PetscInt coneNew[2], coneSize, c, supportSize, s; 1364 1365 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1366 coneNew[0] = vStartNew + (cone[0] - vStart); 1367 coneNew[1] = vStartNew + (cone[1] - vStart); 1368 coneNew[(r+1)%2] = newv; 1369 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1370 #if 1 1371 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1372 for (p = 0; p < 2; ++p) { 1373 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); 1374 } 1375 #endif 1376 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1377 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1378 for (s = 0; s < supportSize; ++s) { 1379 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1380 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1381 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1382 for (c = 0; c < coneSize; ++c) { 1383 if (cone[c] == f) break; 1384 } 1385 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1386 } 1387 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1388 #if 1 1389 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1390 for (p = 0; p < supportSize; ++p) { 1391 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); 1392 } 1393 #endif 1394 } 1395 } 1396 /* Interior faces have 2 vertices and 2 cells */ 1397 for (c = cStart; c < cEnd; ++c) { 1398 const PetscInt *cone; 1399 PetscInt coneNew[2], supportNew[2]; 1400 1401 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1402 for (r = 0; r < 4; ++r) { 1403 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1404 1405 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1406 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1407 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1408 #if 1 1409 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1410 for (p = 0; p < 2; ++p) { 1411 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); 1412 } 1413 #endif 1414 supportNew[0] = (c - cStart)*4 + r; 1415 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1416 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1417 #if 1 1418 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1419 for (p = 0; p < 2; ++p) { 1420 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); 1421 } 1422 #endif 1423 } 1424 } 1425 /* Old vertices have identical supports */ 1426 for (v = vStart; v < vEnd; ++v) { 1427 const PetscInt newp = vStartNew + (v - vStart); 1428 const PetscInt *support, *cone; 1429 PetscInt size, s; 1430 1431 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1432 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1433 for (s = 0; s < size; ++s) { 1434 PetscInt r = 0; 1435 1436 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1437 if (cone[1] == v) r = 1; 1438 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1439 } 1440 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1441 #if 1 1442 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1443 for (p = 0; p < size; ++p) { 1444 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); 1445 } 1446 #endif 1447 } 1448 /* Face vertices have 2 + cells supports */ 1449 for (f = fStart; f < fEnd; ++f) { 1450 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1451 const PetscInt *cone, *support; 1452 PetscInt size, s; 1453 1454 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1455 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1456 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1457 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1458 for (s = 0; s < size; ++s) { 1459 PetscInt r = 0; 1460 1461 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1462 if (cone[1] == f) r = 1; 1463 else if (cone[2] == f) r = 2; 1464 else if (cone[3] == f) r = 3; 1465 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1466 } 1467 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1468 #if 1 1469 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1470 for (p = 0; p < 2+size; ++p) { 1471 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); 1472 } 1473 #endif 1474 } 1475 /* Cell vertices have 4 supports */ 1476 for (c = cStart; c < cEnd; ++c) { 1477 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1478 PetscInt supportNew[4]; 1479 1480 for (r = 0; r < 4; ++r) { 1481 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1482 } 1483 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1484 } 1485 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1486 break; 1487 case 3: 1488 /* Hybrid Simplicial 2D */ 1489 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1490 cMax = PetscMin(cEnd, cMax); 1491 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1492 fMax = PetscMin(fEnd, fMax); 1493 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1494 /* Interior cells have 3 faces */ 1495 for (c = cStart; c < cMax; ++c) { 1496 const PetscInt newp = cStartNew + (c - cStart)*4; 1497 const PetscInt *cone, *ornt; 1498 PetscInt coneNew[3], orntNew[3]; 1499 1500 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1501 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1502 /* A triangle */ 1503 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1504 orntNew[0] = ornt[0]; 1505 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1506 orntNew[1] = -2; 1507 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1508 orntNew[2] = ornt[2]; 1509 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1510 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1511 #if 1 1512 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); 1513 for (p = 0; p < 3; ++p) { 1514 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); 1515 } 1516 #endif 1517 /* B triangle */ 1518 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1519 orntNew[0] = ornt[0]; 1520 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1521 orntNew[1] = ornt[1]; 1522 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1523 orntNew[2] = -2; 1524 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1525 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1526 #if 1 1527 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); 1528 for (p = 0; p < 3; ++p) { 1529 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); 1530 } 1531 #endif 1532 /* C triangle */ 1533 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1534 orntNew[0] = -2; 1535 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1536 orntNew[1] = ornt[1]; 1537 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1538 orntNew[2] = ornt[2]; 1539 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1540 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1541 #if 1 1542 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); 1543 for (p = 0; p < 3; ++p) { 1544 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); 1545 } 1546 #endif 1547 /* D triangle */ 1548 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1549 orntNew[0] = 0; 1550 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1551 orntNew[1] = 0; 1552 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1553 orntNew[2] = 0; 1554 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1555 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1556 #if 1 1557 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); 1558 for (p = 0; p < 3; ++p) { 1559 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); 1560 } 1561 #endif 1562 } 1563 /* 1564 2----3----3 1565 | | 1566 | B | 1567 | | 1568 0----4--- 1 1569 | | 1570 | A | 1571 | | 1572 0----2----1 1573 */ 1574 /* Hybrid cells have 4 faces */ 1575 for (c = cMax; c < cEnd; ++c) { 1576 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1577 const PetscInt *cone, *ornt; 1578 PetscInt coneNew[4], orntNew[4], r; 1579 1580 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1581 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1582 r = (ornt[0] < 0 ? 1 : 0); 1583 /* A quad */ 1584 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 1585 orntNew[0] = ornt[0]; 1586 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 1587 orntNew[1] = ornt[1]; 1588 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 1589 orntNew[2+r] = 0; 1590 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1591 orntNew[3-r] = 0; 1592 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1593 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1594 #if 1 1595 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); 1596 for (p = 0; p < 4; ++p) { 1597 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); 1598 } 1599 #endif 1600 /* B quad */ 1601 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 1602 orntNew[0] = ornt[0]; 1603 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 1604 orntNew[1] = ornt[1]; 1605 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1606 orntNew[2+r] = 0; 1607 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 1608 orntNew[3-r] = 0; 1609 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1610 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1611 #if 1 1612 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); 1613 for (p = 0; p < 4; ++p) { 1614 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); 1615 } 1616 #endif 1617 } 1618 /* Interior split faces have 2 vertices and the same cells as the parent */ 1619 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1620 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1621 for (f = fStart; f < fMax; ++f) { 1622 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1623 1624 for (r = 0; r < 2; ++r) { 1625 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1626 const PetscInt *cone, *ornt, *support; 1627 PetscInt coneNew[2], coneSize, c, supportSize, s; 1628 1629 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1630 coneNew[0] = vStartNew + (cone[0] - vStart); 1631 coneNew[1] = vStartNew + (cone[1] - vStart); 1632 coneNew[(r+1)%2] = newv; 1633 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1634 #if 1 1635 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1636 for (p = 0; p < 2; ++p) { 1637 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); 1638 } 1639 #endif 1640 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1641 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1642 for (s = 0; s < supportSize; ++s) { 1643 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1644 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1645 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1646 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 1647 if (support[s] >= cMax) { 1648 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 1649 } else { 1650 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1651 } 1652 } 1653 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1654 #if 1 1655 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1656 for (p = 0; p < supportSize; ++p) { 1657 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); 1658 } 1659 #endif 1660 } 1661 } 1662 /* Interior cell faces have 2 vertices and 2 cells */ 1663 for (c = cStart; c < cMax; ++c) { 1664 const PetscInt *cone; 1665 1666 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1667 for (r = 0; r < 3; ++r) { 1668 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1669 PetscInt coneNew[2]; 1670 PetscInt supportNew[2]; 1671 1672 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1673 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1674 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1675 #if 1 1676 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1677 for (p = 0; p < 2; ++p) { 1678 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); 1679 } 1680 #endif 1681 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1682 supportNew[1] = (c - cStart)*4 + 3; 1683 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1684 #if 1 1685 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1686 for (p = 0; p < 2; ++p) { 1687 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); 1688 } 1689 #endif 1690 } 1691 } 1692 /* Interior hybrid faces have 2 vertices and the same cells */ 1693 for (f = fMax; f < fEnd; ++f) { 1694 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1695 const PetscInt *cone, *ornt; 1696 const PetscInt *support; 1697 PetscInt coneNew[2]; 1698 PetscInt supportNew[2]; 1699 PetscInt size, s, r; 1700 1701 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1702 coneNew[0] = vStartNew + (cone[0] - vStart); 1703 coneNew[1] = vStartNew + (cone[1] - vStart); 1704 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1705 #if 1 1706 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1707 for (p = 0; p < 2; ++p) { 1708 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); 1709 } 1710 #endif 1711 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1712 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1713 for (s = 0; s < size; ++s) { 1714 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1715 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1716 for (r = 0; r < 2; ++r) { 1717 if (cone[r+2] == f) break; 1718 } 1719 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 1720 } 1721 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1722 #if 1 1723 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1724 for (p = 0; p < size; ++p) { 1725 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); 1726 } 1727 #endif 1728 } 1729 /* Cell hybrid faces have 2 vertices and 2 cells */ 1730 for (c = cMax; c < cEnd; ++c) { 1731 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1732 const PetscInt *cone; 1733 PetscInt coneNew[2]; 1734 PetscInt supportNew[2]; 1735 1736 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1737 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1738 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1739 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1740 #if 1 1741 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1742 for (p = 0; p < 2; ++p) { 1743 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); 1744 } 1745 #endif 1746 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1747 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1748 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1749 #if 1 1750 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1751 for (p = 0; p < 2; ++p) { 1752 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); 1753 } 1754 #endif 1755 } 1756 /* Old vertices have identical supports */ 1757 for (v = vStart; v < vEnd; ++v) { 1758 const PetscInt newp = vStartNew + (v - vStart); 1759 const PetscInt *support, *cone; 1760 PetscInt size, s; 1761 1762 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1763 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1764 for (s = 0; s < size; ++s) { 1765 if (support[s] >= fMax) { 1766 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1767 } else { 1768 PetscInt r = 0; 1769 1770 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1771 if (cone[1] == v) r = 1; 1772 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1773 } 1774 } 1775 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1776 #if 1 1777 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1778 for (p = 0; p < size; ++p) { 1779 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); 1780 } 1781 #endif 1782 } 1783 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1784 for (f = fStart; f < fMax; ++f) { 1785 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1786 const PetscInt *cone, *support; 1787 PetscInt size, newSize = 2, s; 1788 1789 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1790 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1791 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1792 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1793 for (s = 0; s < size; ++s) { 1794 PetscInt r = 0; 1795 1796 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1797 if (support[s] >= cMax) { 1798 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1799 1800 newSize += 1; 1801 } else { 1802 if (cone[1] == f) r = 1; 1803 else if (cone[2] == f) r = 2; 1804 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1805 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1806 1807 newSize += 2; 1808 } 1809 } 1810 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1811 #if 1 1812 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1813 for (p = 0; p < newSize; ++p) { 1814 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); 1815 } 1816 #endif 1817 } 1818 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1819 break; 1820 case 4: 1821 /* Hybrid Hex 2D */ 1822 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1823 cMax = PetscMin(cEnd, cMax); 1824 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1825 fMax = PetscMin(fEnd, fMax); 1826 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1827 /* Interior cells have 4 faces */ 1828 for (c = cStart; c < cMax; ++c) { 1829 const PetscInt newp = cStartNew + (c - cStart)*4; 1830 const PetscInt *cone, *ornt; 1831 PetscInt coneNew[4], orntNew[4]; 1832 1833 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1834 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1835 /* A quad */ 1836 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1837 orntNew[0] = ornt[0]; 1838 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1839 orntNew[1] = 0; 1840 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1841 orntNew[2] = -2; 1842 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1843 orntNew[3] = ornt[3]; 1844 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1845 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1846 #if 1 1847 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); 1848 for (p = 0; p < 4; ++p) { 1849 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); 1850 } 1851 #endif 1852 /* B quad */ 1853 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1854 orntNew[0] = ornt[0]; 1855 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1856 orntNew[1] = ornt[1]; 1857 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1858 orntNew[2] = 0; 1859 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1860 orntNew[3] = -2; 1861 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1862 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1863 #if 1 1864 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); 1865 for (p = 0; p < 4; ++p) { 1866 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); 1867 } 1868 #endif 1869 /* C quad */ 1870 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1871 orntNew[0] = -2; 1872 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1873 orntNew[1] = ornt[1]; 1874 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1875 orntNew[2] = ornt[2]; 1876 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1877 orntNew[3] = 0; 1878 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1879 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1880 #if 1 1881 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); 1882 for (p = 0; p < 4; ++p) { 1883 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); 1884 } 1885 #endif 1886 /* D quad */ 1887 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1888 orntNew[0] = 0; 1889 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1890 orntNew[1] = -2; 1891 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1892 orntNew[2] = ornt[2]; 1893 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1894 orntNew[3] = ornt[3]; 1895 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1896 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1897 #if 1 1898 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); 1899 for (p = 0; p < 4; ++p) { 1900 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); 1901 } 1902 #endif 1903 } 1904 /* 1905 2----3----3 1906 | | 1907 | B | 1908 | | 1909 0----4--- 1 1910 | | 1911 | A | 1912 | | 1913 0----2----1 1914 */ 1915 /* Hybrid cells have 4 faces */ 1916 for (c = cMax; c < cEnd; ++c) { 1917 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1918 const PetscInt *cone, *ornt; 1919 PetscInt coneNew[4], orntNew[4]; 1920 1921 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1922 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1923 /* A quad */ 1924 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1925 orntNew[0] = ornt[0]; 1926 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1927 orntNew[1] = ornt[1]; 1928 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 1929 orntNew[2] = 0; 1930 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 1931 orntNew[3] = 0; 1932 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1933 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1934 #if 1 1935 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); 1936 for (p = 0; p < 4; ++p) { 1937 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); 1938 } 1939 #endif 1940 /* B quad */ 1941 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1942 orntNew[0] = ornt[0]; 1943 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1944 orntNew[1] = ornt[1]; 1945 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 1946 orntNew[2] = 0; 1947 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 1948 orntNew[3] = 0; 1949 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1950 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1951 #if 1 1952 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); 1953 for (p = 0; p < 4; ++p) { 1954 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); 1955 } 1956 #endif 1957 } 1958 /* Interior split faces have 2 vertices and the same cells as the parent */ 1959 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1960 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 1961 for (f = fStart; f < fMax; ++f) { 1962 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1963 1964 for (r = 0; r < 2; ++r) { 1965 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1966 const PetscInt *cone, *ornt, *support; 1967 PetscInt coneNew[2], coneSize, c, supportSize, s; 1968 1969 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1970 coneNew[0] = vStartNew + (cone[0] - vStart); 1971 coneNew[1] = vStartNew + (cone[1] - vStart); 1972 coneNew[(r+1)%2] = newv; 1973 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1974 #if 1 1975 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1976 for (p = 0; p < 2; ++p) { 1977 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); 1978 } 1979 #endif 1980 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1981 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1982 for (s = 0; s < supportSize; ++s) { 1983 if (support[s] >= cMax) { 1984 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 1985 } else { 1986 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1987 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1988 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1989 for (c = 0; c < coneSize; ++c) { 1990 if (cone[c] == f) break; 1991 } 1992 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1993 } 1994 } 1995 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1996 #if 1 1997 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1998 for (p = 0; p < supportSize; ++p) { 1999 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); 2000 } 2001 #endif 2002 } 2003 } 2004 /* Interior cell faces have 2 vertices and 2 cells */ 2005 for (c = cStart; c < cMax; ++c) { 2006 const PetscInt *cone; 2007 2008 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2009 for (r = 0; r < 4; ++r) { 2010 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2011 PetscInt coneNew[2], supportNew[2]; 2012 2013 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2014 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2015 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2016 #if 1 2017 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2018 for (p = 0; p < 2; ++p) { 2019 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); 2020 } 2021 #endif 2022 supportNew[0] = (c - cStart)*4 + r; 2023 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2024 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2025 #if 1 2026 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2027 for (p = 0; p < 2; ++p) { 2028 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); 2029 } 2030 #endif 2031 } 2032 } 2033 /* Hybrid faces have 2 vertices and the same cells */ 2034 for (f = fMax; f < fEnd; ++f) { 2035 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 2036 const PetscInt *cone, *support; 2037 PetscInt coneNew[2], supportNew[2]; 2038 PetscInt size, s, r; 2039 2040 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2041 coneNew[0] = vStartNew + (cone[0] - vStart); 2042 coneNew[1] = vStartNew + (cone[1] - vStart); 2043 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2044 #if 1 2045 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2046 for (p = 0; p < 2; ++p) { 2047 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); 2048 } 2049 #endif 2050 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2051 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2052 for (s = 0; s < size; ++s) { 2053 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2054 for (r = 0; r < 2; ++r) { 2055 if (cone[r+2] == f) break; 2056 } 2057 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2058 } 2059 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2060 #if 1 2061 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2062 for (p = 0; p < size; ++p) { 2063 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); 2064 } 2065 #endif 2066 } 2067 /* Cell hybrid faces have 2 vertices and 2 cells */ 2068 for (c = cMax; c < cEnd; ++c) { 2069 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2070 const PetscInt *cone; 2071 PetscInt coneNew[2], supportNew[2]; 2072 2073 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2074 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2075 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2076 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2077 #if 1 2078 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2079 for (p = 0; p < 2; ++p) { 2080 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); 2081 } 2082 #endif 2083 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2084 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2085 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2086 #if 1 2087 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2088 for (p = 0; p < 2; ++p) { 2089 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); 2090 } 2091 #endif 2092 } 2093 /* Old vertices have identical supports */ 2094 for (v = vStart; v < vEnd; ++v) { 2095 const PetscInt newp = vStartNew + (v - vStart); 2096 const PetscInt *support, *cone; 2097 PetscInt size, s; 2098 2099 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2100 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2101 for (s = 0; s < size; ++s) { 2102 if (support[s] >= fMax) { 2103 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2104 } else { 2105 PetscInt r = 0; 2106 2107 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2108 if (cone[1] == v) r = 1; 2109 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2110 } 2111 } 2112 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2113 #if 1 2114 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2115 for (p = 0; p < size; ++p) { 2116 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); 2117 } 2118 #endif 2119 } 2120 /* Face vertices have 2 + cells supports */ 2121 for (f = fStart; f < fMax; ++f) { 2122 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2123 const PetscInt *cone, *support; 2124 PetscInt size, s; 2125 2126 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2127 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2128 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2129 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2130 for (s = 0; s < size; ++s) { 2131 PetscInt r = 0; 2132 2133 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2134 if (support[s] >= cMax) { 2135 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2136 } else { 2137 if (cone[1] == f) r = 1; 2138 else if (cone[2] == f) r = 2; 2139 else if (cone[3] == f) r = 3; 2140 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2141 } 2142 } 2143 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2144 #if 1 2145 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2146 for (p = 0; p < 2+size; ++p) { 2147 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); 2148 } 2149 #endif 2150 } 2151 /* Cell vertices have 4 supports */ 2152 for (c = cStart; c < cMax; ++c) { 2153 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2154 PetscInt supportNew[4]; 2155 2156 for (r = 0; r < 4; ++r) { 2157 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2158 } 2159 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2160 } 2161 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2162 break; 2163 case 5: 2164 /* Simplicial 3D */ 2165 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2166 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2167 for (c = cStart; c < cEnd; ++c) { 2168 const PetscInt newp = cStartNew + (c - cStart)*8; 2169 const PetscInt *cone, *ornt; 2170 PetscInt coneNew[4], orntNew[4]; 2171 2172 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2173 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2174 /* A tetrahedron: {0, a, c, d} */ 2175 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2176 orntNew[0] = ornt[0]; 2177 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2178 orntNew[1] = ornt[1]; 2179 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2180 orntNew[2] = ornt[2]; 2181 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2182 orntNew[3] = 0; 2183 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2184 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2185 #if 1 2186 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); 2187 for (p = 0; p < 4; ++p) { 2188 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); 2189 } 2190 #endif 2191 /* B tetrahedron: {a, 1, b, e} */ 2192 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2193 orntNew[0] = ornt[0]; 2194 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2195 orntNew[1] = ornt[1]; 2196 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2197 orntNew[2] = 0; 2198 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2199 orntNew[3] = ornt[3]; 2200 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2201 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2202 #if 1 2203 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); 2204 for (p = 0; p < 4; ++p) { 2205 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); 2206 } 2207 #endif 2208 /* C tetrahedron: {c, b, 2, f} */ 2209 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2210 orntNew[0] = ornt[0]; 2211 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2212 orntNew[1] = 0; 2213 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2214 orntNew[2] = ornt[2]; 2215 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2216 orntNew[3] = ornt[3]; 2217 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2218 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2219 #if 1 2220 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); 2221 for (p = 0; p < 4; ++p) { 2222 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); 2223 } 2224 #endif 2225 /* D tetrahedron: {d, e, f, 3} */ 2226 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2227 orntNew[0] = 0; 2228 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2229 orntNew[1] = ornt[1]; 2230 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2231 orntNew[2] = ornt[2]; 2232 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2233 orntNew[3] = ornt[3]; 2234 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2235 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2236 #if 1 2237 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); 2238 for (p = 0; p < 4; ++p) { 2239 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); 2240 } 2241 #endif 2242 /* A' tetrahedron: {d, a, c, f} */ 2243 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2244 orntNew[0] = -3; 2245 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2246 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2247 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2248 orntNew[2] = 0; 2249 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2250 orntNew[3] = 2; 2251 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2252 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2253 #if 1 2254 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); 2255 for (p = 0; p < 4; ++p) { 2256 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); 2257 } 2258 #endif 2259 /* B' tetrahedron: {e, b, a, f} */ 2260 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2261 orntNew[0] = -3; 2262 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2263 orntNew[1] = 1; 2264 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2265 orntNew[2] = 0; 2266 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2267 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2268 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2269 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2270 #if 1 2271 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); 2272 for (p = 0; p < 4; ++p) { 2273 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); 2274 } 2275 #endif 2276 /* C' tetrahedron: {b, f, c, a} */ 2277 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2278 orntNew[0] = -3; 2279 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2280 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2281 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2282 orntNew[2] = -3; 2283 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2284 orntNew[3] = -2; 2285 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2286 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2287 #if 1 2288 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); 2289 for (p = 0; p < 4; ++p) { 2290 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); 2291 } 2292 #endif 2293 /* D' tetrahedron: {f, e, d, a} */ 2294 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2295 orntNew[0] = -3; 2296 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2297 orntNew[1] = -3; 2298 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2299 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2300 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2301 orntNew[3] = -3; 2302 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2303 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2304 #if 1 2305 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); 2306 for (p = 0; p < 4; ++p) { 2307 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); 2308 } 2309 #endif 2310 } 2311 /* Split faces have 3 edges and the same cells as the parent */ 2312 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2313 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 2314 for (f = fStart; f < fEnd; ++f) { 2315 const PetscInt newp = fStartNew + (f - fStart)*4; 2316 const PetscInt *cone, *ornt, *support; 2317 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2318 2319 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2320 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2321 /* A triangle */ 2322 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2323 orntNew[0] = ornt[0]; 2324 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2325 orntNew[1] = -2; 2326 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2327 orntNew[2] = ornt[2]; 2328 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2329 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2330 #if 1 2331 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); 2332 for (p = 0; p < 3; ++p) { 2333 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); 2334 } 2335 #endif 2336 /* B triangle */ 2337 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2338 orntNew[0] = ornt[0]; 2339 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2340 orntNew[1] = ornt[1]; 2341 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2342 orntNew[2] = -2; 2343 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2344 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2345 #if 1 2346 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); 2347 for (p = 0; p < 3; ++p) { 2348 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); 2349 } 2350 #endif 2351 /* C triangle */ 2352 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2353 orntNew[0] = -2; 2354 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2355 orntNew[1] = ornt[1]; 2356 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2357 orntNew[2] = ornt[2]; 2358 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2359 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2360 #if 1 2361 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); 2362 for (p = 0; p < 3; ++p) { 2363 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); 2364 } 2365 #endif 2366 /* D triangle */ 2367 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2368 orntNew[0] = 0; 2369 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2370 orntNew[1] = 0; 2371 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2372 orntNew[2] = 0; 2373 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2374 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2375 #if 1 2376 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); 2377 for (p = 0; p < 3; ++p) { 2378 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); 2379 } 2380 #endif 2381 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2382 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2383 for (r = 0; r < 4; ++r) { 2384 for (s = 0; s < supportSize; ++s) { 2385 PetscInt subf; 2386 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2387 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2388 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2389 for (c = 0; c < coneSize; ++c) { 2390 if (cone[c] == f) break; 2391 } 2392 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2393 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2394 } 2395 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2396 #if 1 2397 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); 2398 for (p = 0; p < supportSize; ++p) { 2399 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); 2400 } 2401 #endif 2402 } 2403 } 2404 /* Interior faces have 3 edges and 2 cells */ 2405 for (c = cStart; c < cEnd; ++c) { 2406 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2407 const PetscInt *cone, *ornt; 2408 PetscInt coneNew[3], orntNew[3]; 2409 PetscInt supportNew[2]; 2410 2411 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2412 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2413 /* Face A: {c, a, d} */ 2414 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2415 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2416 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2417 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2418 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2419 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2420 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2421 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2422 #if 1 2423 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2424 for (p = 0; p < 3; ++p) { 2425 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); 2426 } 2427 #endif 2428 supportNew[0] = (c - cStart)*8 + 0; 2429 supportNew[1] = (c - cStart)*8 + 0+4; 2430 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2431 #if 1 2432 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2433 for (p = 0; p < 2; ++p) { 2434 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); 2435 } 2436 #endif 2437 ++newp; 2438 /* Face B: {a, b, e} */ 2439 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2440 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2441 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2442 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2443 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2444 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2445 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2446 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2447 #if 1 2448 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2449 for (p = 0; p < 3; ++p) { 2450 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); 2451 } 2452 #endif 2453 supportNew[0] = (c - cStart)*8 + 1; 2454 supportNew[1] = (c - cStart)*8 + 1+4; 2455 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2456 #if 1 2457 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2458 for (p = 0; p < 2; ++p) { 2459 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); 2460 } 2461 #endif 2462 ++newp; 2463 /* Face C: {c, f, b} */ 2464 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2465 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2466 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2467 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2468 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2469 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2470 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2471 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2472 #if 1 2473 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2474 for (p = 0; p < 3; ++p) { 2475 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); 2476 } 2477 #endif 2478 supportNew[0] = (c - cStart)*8 + 2; 2479 supportNew[1] = (c - cStart)*8 + 2+4; 2480 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2481 #if 1 2482 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2483 for (p = 0; p < 2; ++p) { 2484 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); 2485 } 2486 #endif 2487 ++newp; 2488 /* Face D: {d, e, f} */ 2489 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2490 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2491 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2492 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2493 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2494 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2495 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2496 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2497 #if 1 2498 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2499 for (p = 0; p < 3; ++p) { 2500 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); 2501 } 2502 #endif 2503 supportNew[0] = (c - cStart)*8 + 3; 2504 supportNew[1] = (c - cStart)*8 + 3+4; 2505 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2506 #if 1 2507 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2508 for (p = 0; p < 2; ++p) { 2509 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); 2510 } 2511 #endif 2512 ++newp; 2513 /* Face E: {d, f, a} */ 2514 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2515 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2516 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2517 orntNew[1] = -2; 2518 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2519 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2520 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2521 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2522 #if 1 2523 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2524 for (p = 0; p < 3; ++p) { 2525 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); 2526 } 2527 #endif 2528 supportNew[0] = (c - cStart)*8 + 0+4; 2529 supportNew[1] = (c - cStart)*8 + 3+4; 2530 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2531 #if 1 2532 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2533 for (p = 0; p < 2; ++p) { 2534 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); 2535 } 2536 #endif 2537 ++newp; 2538 /* Face F: {c, a, f} */ 2539 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2540 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2541 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2542 orntNew[1] = 0; 2543 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2544 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2545 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2546 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2547 #if 1 2548 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2549 for (p = 0; p < 3; ++p) { 2550 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); 2551 } 2552 #endif 2553 supportNew[0] = (c - cStart)*8 + 0+4; 2554 supportNew[1] = (c - cStart)*8 + 2+4; 2555 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2556 #if 1 2557 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2558 for (p = 0; p < 2; ++p) { 2559 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); 2560 } 2561 #endif 2562 ++newp; 2563 /* Face G: {e, a, f} */ 2564 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2565 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2566 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2567 orntNew[1] = 0; 2568 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2569 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2570 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2571 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2572 #if 1 2573 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2574 for (p = 0; p < 3; ++p) { 2575 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); 2576 } 2577 #endif 2578 supportNew[0] = (c - cStart)*8 + 1+4; 2579 supportNew[1] = (c - cStart)*8 + 3+4; 2580 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2581 #if 1 2582 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2583 for (p = 0; p < 2; ++p) { 2584 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); 2585 } 2586 #endif 2587 ++newp; 2588 /* Face H: {a, b, f} */ 2589 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2590 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2591 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2592 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2593 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2594 orntNew[2] = -2; 2595 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2596 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2597 #if 1 2598 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2599 for (p = 0; p < 3; ++p) { 2600 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); 2601 } 2602 #endif 2603 supportNew[0] = (c - cStart)*8 + 1+4; 2604 supportNew[1] = (c - cStart)*8 + 2+4; 2605 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2606 #if 1 2607 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2608 for (p = 0; p < 2; ++p) { 2609 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); 2610 } 2611 #endif 2612 ++newp; 2613 } 2614 /* Split Edges have 2 vertices and the same faces as the parent */ 2615 for (e = eStart; e < eEnd; ++e) { 2616 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2617 2618 for (r = 0; r < 2; ++r) { 2619 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2620 const PetscInt *cone, *ornt, *support; 2621 PetscInt coneNew[2], coneSize, c, supportSize, s; 2622 2623 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2624 coneNew[0] = vStartNew + (cone[0] - vStart); 2625 coneNew[1] = vStartNew + (cone[1] - vStart); 2626 coneNew[(r+1)%2] = newv; 2627 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2628 #if 1 2629 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2630 for (p = 0; p < 2; ++p) { 2631 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); 2632 } 2633 #endif 2634 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2635 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2636 for (s = 0; s < supportSize; ++s) { 2637 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2638 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2639 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2640 for (c = 0; c < coneSize; ++c) { 2641 if (cone[c] == e) break; 2642 } 2643 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2644 } 2645 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2646 #if 1 2647 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2648 for (p = 0; p < supportSize; ++p) { 2649 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); 2650 } 2651 #endif 2652 } 2653 } 2654 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2655 for (f = fStart; f < fEnd; ++f) { 2656 const PetscInt *cone, *ornt, *support; 2657 PetscInt coneSize, supportSize, s; 2658 2659 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2660 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2661 for (r = 0; r < 3; ++r) { 2662 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2663 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2664 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2665 -1, -1, 1, 6, 0, 4, 2666 2, 5, 3, 4, -1, -1, 2667 -1, -1, 3, 6, 2, 7}; 2668 2669 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2670 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2671 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2672 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2673 #if 1 2674 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2675 for (p = 0; p < 2; ++p) { 2676 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); 2677 } 2678 #endif 2679 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2680 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2681 for (s = 0; s < supportSize; ++s) { 2682 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2683 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2684 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2685 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2686 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2687 er = GetTetSomethingInverse_Static(ornt[c], r); 2688 if (er == eint[c]) { 2689 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2690 } else { 2691 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2692 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2693 } 2694 } 2695 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2696 #if 1 2697 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2698 for (p = 0; p < intFaces; ++p) { 2699 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); 2700 } 2701 #endif 2702 } 2703 } 2704 /* Interior edges have 2 vertices and 4 faces */ 2705 for (c = cStart; c < cEnd; ++c) { 2706 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2707 const PetscInt *cone, *ornt, *fcone; 2708 PetscInt coneNew[2], supportNew[4], find; 2709 2710 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2711 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2712 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2713 find = GetTriEdge_Static(ornt[0], 0); 2714 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2715 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2716 find = GetTriEdge_Static(ornt[2], 1); 2717 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2718 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2719 #if 1 2720 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2721 for (p = 0; p < 2; ++p) { 2722 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); 2723 } 2724 #endif 2725 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2726 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2727 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2728 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2729 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2730 #if 1 2731 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2732 for (p = 0; p < 4; ++p) { 2733 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); 2734 } 2735 #endif 2736 } 2737 /* Old vertices have identical supports */ 2738 for (v = vStart; v < vEnd; ++v) { 2739 const PetscInt newp = vStartNew + (v - vStart); 2740 const PetscInt *support, *cone; 2741 PetscInt size, s; 2742 2743 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2744 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2745 for (s = 0; s < size; ++s) { 2746 PetscInt r = 0; 2747 2748 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2749 if (cone[1] == v) r = 1; 2750 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2751 } 2752 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2753 #if 1 2754 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2755 for (p = 0; p < size; ++p) { 2756 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); 2757 } 2758 #endif 2759 } 2760 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2761 for (e = eStart; e < eEnd; ++e) { 2762 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2763 const PetscInt *cone, *support; 2764 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2765 2766 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2767 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2768 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2769 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2770 for (s = 0; s < size; ++s) { 2771 PetscInt r = 0; 2772 2773 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2774 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2775 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2776 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2777 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2778 } 2779 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2780 for (s = 0; s < starSize*2; s += 2) { 2781 const PetscInt *cone, *ornt; 2782 PetscInt e01, e23; 2783 2784 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2785 /* Check edge 0-1 */ 2786 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2787 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2788 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2789 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2790 /* Check edge 2-3 */ 2791 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2792 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2793 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2794 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2795 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2796 } 2797 } 2798 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2799 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2800 #if 1 2801 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2802 for (p = 0; p < 2+size*2+cellSize; ++p) { 2803 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); 2804 } 2805 #endif 2806 } 2807 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2808 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2809 break; 2810 case 7: 2811 /* Hybrid Simplicial 3D */ 2812 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2813 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2814 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2815 for (c = cStart; c < cMax; ++c) { 2816 const PetscInt newp = cStartNew + (c - cStart)*8; 2817 const PetscInt *cone, *ornt; 2818 PetscInt coneNew[4], orntNew[4]; 2819 2820 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2821 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2822 /* A tetrahedron: {0, a, c, d} */ 2823 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2824 orntNew[0] = ornt[0]; 2825 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2826 orntNew[1] = ornt[1]; 2827 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2828 orntNew[2] = ornt[2]; 2829 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2830 orntNew[3] = 0; 2831 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2832 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2833 #if 1 2834 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); 2835 for (p = 0; p < 4; ++p) { 2836 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); 2837 } 2838 #endif 2839 /* B tetrahedron: {a, 1, b, e} */ 2840 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2841 orntNew[0] = ornt[0]; 2842 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2843 orntNew[1] = ornt[1]; 2844 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2845 orntNew[2] = 0; 2846 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2847 orntNew[3] = ornt[3]; 2848 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2849 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2850 #if 1 2851 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); 2852 for (p = 0; p < 4; ++p) { 2853 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); 2854 } 2855 #endif 2856 /* C tetrahedron: {c, b, 2, f} */ 2857 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2858 orntNew[0] = ornt[0]; 2859 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2860 orntNew[1] = 0; 2861 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2862 orntNew[2] = ornt[2]; 2863 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2864 orntNew[3] = ornt[3]; 2865 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2866 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2867 #if 1 2868 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); 2869 for (p = 0; p < 4; ++p) { 2870 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); 2871 } 2872 #endif 2873 /* D tetrahedron: {d, e, f, 3} */ 2874 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2875 orntNew[0] = 0; 2876 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2877 orntNew[1] = ornt[1]; 2878 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2879 orntNew[2] = ornt[2]; 2880 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2881 orntNew[3] = ornt[3]; 2882 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2883 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2884 #if 1 2885 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); 2886 for (p = 0; p < 4; ++p) { 2887 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); 2888 } 2889 #endif 2890 /* A' tetrahedron: {d, a, c, f} */ 2891 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2892 orntNew[0] = -3; 2893 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2894 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2895 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2896 orntNew[2] = 0; 2897 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2898 orntNew[3] = 2; 2899 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2900 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2901 #if 1 2902 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); 2903 for (p = 0; p < 4; ++p) { 2904 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); 2905 } 2906 #endif 2907 /* B' tetrahedron: {e, b, a, f} */ 2908 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2909 orntNew[0] = -3; 2910 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2911 orntNew[1] = 1; 2912 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2913 orntNew[2] = 0; 2914 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2915 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2916 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2917 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2918 #if 1 2919 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); 2920 for (p = 0; p < 4; ++p) { 2921 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); 2922 } 2923 #endif 2924 /* C' tetrahedron: {b, f, c, a} */ 2925 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2926 orntNew[0] = -3; 2927 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2928 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2929 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2930 orntNew[2] = -3; 2931 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2932 orntNew[3] = -2; 2933 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2934 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2935 #if 1 2936 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); 2937 for (p = 0; p < 4; ++p) { 2938 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); 2939 } 2940 #endif 2941 /* D' tetrahedron: {f, e, d, a} */ 2942 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2943 orntNew[0] = -3; 2944 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2945 orntNew[1] = -3; 2946 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2947 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2948 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2949 orntNew[3] = -3; 2950 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2951 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2952 #if 1 2953 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); 2954 for (p = 0; p < 4; ++p) { 2955 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2956 } 2957 #endif 2958 } 2959 /* Hybrid cells have 5 faces */ 2960 for (c = cMax; c < cEnd; ++c) { 2961 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 2962 const PetscInt *cone, *ornt, *fornt; 2963 PetscInt coneNew[5], orntNew[5], o, of, i; 2964 2965 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2966 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2967 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 2968 o = ornt[0] < 0 ? -1 : 1; 2969 for (r = 0; r < 3; ++r) { 2970 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 2971 orntNew[0] = ornt[0]; 2972 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 2973 orntNew[1] = ornt[1]; 2974 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 2975 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 2976 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 2977 orntNew[i] = 0; 2978 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 2979 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 2980 orntNew[i] = 0; 2981 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 2982 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 2983 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); 2984 orntNew[i] = 0; 2985 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 2986 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 2987 #if 1 2988 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); 2989 for (p = 0; p < 2; ++p) { 2990 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); 2991 } 2992 for (p = 2; p < 5; ++p) { 2993 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); 2994 } 2995 #endif 2996 } 2997 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 2998 orntNew[0] = 0; 2999 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3000 orntNew[1] = 0; 3001 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3002 orntNew[2] = 0; 3003 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3004 orntNew[3] = 0; 3005 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3006 orntNew[4] = 0; 3007 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3008 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3009 #if 1 3010 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); 3011 for (p = 0; p < 2; ++p) { 3012 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); 3013 } 3014 for (p = 2; p < 5; ++p) { 3015 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); 3016 } 3017 #endif 3018 } 3019 /* Split faces have 3 edges and the same cells as the parent */ 3020 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3021 ierr = PetscMalloc1((2 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3022 for (f = fStart; f < fMax; ++f) { 3023 const PetscInt newp = fStartNew + (f - fStart)*4; 3024 const PetscInt *cone, *ornt, *support; 3025 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3026 3027 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3028 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3029 /* A triangle */ 3030 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3031 orntNew[0] = ornt[0]; 3032 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3033 orntNew[1] = -2; 3034 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3035 orntNew[2] = ornt[2]; 3036 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3037 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3038 #if 1 3039 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); 3040 for (p = 0; p < 3; ++p) { 3041 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); 3042 } 3043 #endif 3044 /* B triangle */ 3045 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3046 orntNew[0] = ornt[0]; 3047 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3048 orntNew[1] = ornt[1]; 3049 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3050 orntNew[2] = -2; 3051 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3052 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3053 #if 1 3054 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); 3055 for (p = 0; p < 3; ++p) { 3056 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); 3057 } 3058 #endif 3059 /* C triangle */ 3060 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3061 orntNew[0] = -2; 3062 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3063 orntNew[1] = ornt[1]; 3064 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3065 orntNew[2] = ornt[2]; 3066 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3067 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3068 #if 1 3069 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); 3070 for (p = 0; p < 3; ++p) { 3071 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); 3072 } 3073 #endif 3074 /* D triangle */ 3075 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3076 orntNew[0] = 0; 3077 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3078 orntNew[1] = 0; 3079 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3080 orntNew[2] = 0; 3081 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3082 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3083 #if 1 3084 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); 3085 for (p = 0; p < 3; ++p) { 3086 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); 3087 } 3088 #endif 3089 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3090 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3091 for (r = 0; r < 4; ++r) { 3092 for (s = 0; s < supportSize; ++s) { 3093 PetscInt subf; 3094 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3095 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3096 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3097 for (c = 0; c < coneSize; ++c) { 3098 if (cone[c] == f) break; 3099 } 3100 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3101 if (support[s] < cMax) { 3102 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3103 } else { 3104 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3105 } 3106 } 3107 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3108 #if 1 3109 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); 3110 for (p = 0; p < supportSize; ++p) { 3111 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); 3112 } 3113 #endif 3114 } 3115 } 3116 /* Interior cell faces have 3 edges and 2 cells */ 3117 for (c = cStart; c < cMax; ++c) { 3118 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3119 const PetscInt *cone, *ornt; 3120 PetscInt coneNew[3], orntNew[3]; 3121 PetscInt supportNew[2]; 3122 3123 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3124 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3125 /* Face A: {c, a, d} */ 3126 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3127 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3128 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3129 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3130 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 3131 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3132 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3133 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3134 #if 1 3135 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3136 for (p = 0; p < 3; ++p) { 3137 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 3138 } 3139 #endif 3140 supportNew[0] = (c - cStart)*8 + 0; 3141 supportNew[1] = (c - cStart)*8 + 0+4; 3142 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3143 #if 1 3144 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3145 for (p = 0; p < 2; ++p) { 3146 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); 3147 } 3148 #endif 3149 ++newp; 3150 /* Face B: {a, b, e} */ 3151 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3152 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3153 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 3154 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3155 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3156 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3157 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3158 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3159 #if 1 3160 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); 3161 for (p = 0; p < 3; ++p) { 3162 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); 3163 } 3164 #endif 3165 supportNew[0] = (c - cStart)*8 + 1; 3166 supportNew[1] = (c - cStart)*8 + 1+4; 3167 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3168 #if 1 3169 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3170 for (p = 0; p < 2; ++p) { 3171 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); 3172 } 3173 #endif 3174 ++newp; 3175 /* Face C: {c, f, b} */ 3176 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3177 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3178 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3179 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3180 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 3181 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3182 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3183 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3184 #if 1 3185 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3186 for (p = 0; p < 3; ++p) { 3187 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); 3188 } 3189 #endif 3190 supportNew[0] = (c - cStart)*8 + 2; 3191 supportNew[1] = (c - cStart)*8 + 2+4; 3192 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3193 #if 1 3194 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3195 for (p = 0; p < 2; ++p) { 3196 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); 3197 } 3198 #endif 3199 ++newp; 3200 /* Face D: {d, e, f} */ 3201 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 3202 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3203 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3204 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3205 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3206 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3207 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3208 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3209 #if 1 3210 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3211 for (p = 0; p < 3; ++p) { 3212 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); 3213 } 3214 #endif 3215 supportNew[0] = (c - cStart)*8 + 3; 3216 supportNew[1] = (c - cStart)*8 + 3+4; 3217 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3218 #if 1 3219 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3220 for (p = 0; p < 2; ++p) { 3221 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); 3222 } 3223 #endif 3224 ++newp; 3225 /* Face E: {d, f, a} */ 3226 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3227 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3228 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3229 orntNew[1] = -2; 3230 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3231 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3232 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3233 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3234 #if 1 3235 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3236 for (p = 0; p < 3; ++p) { 3237 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); 3238 } 3239 #endif 3240 supportNew[0] = (c - cStart)*8 + 0+4; 3241 supportNew[1] = (c - cStart)*8 + 3+4; 3242 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3243 #if 1 3244 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3245 for (p = 0; p < 2; ++p) { 3246 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); 3247 } 3248 #endif 3249 ++newp; 3250 /* Face F: {c, a, f} */ 3251 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3252 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3253 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3254 orntNew[1] = 0; 3255 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3256 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3257 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3258 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3259 #if 1 3260 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3261 for (p = 0; p < 3; ++p) { 3262 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); 3263 } 3264 #endif 3265 supportNew[0] = (c - cStart)*8 + 0+4; 3266 supportNew[1] = (c - cStart)*8 + 2+4; 3267 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3268 #if 1 3269 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3270 for (p = 0; p < 2; ++p) { 3271 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); 3272 } 3273 #endif 3274 ++newp; 3275 /* Face G: {e, a, f} */ 3276 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3277 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3278 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3279 orntNew[1] = 0; 3280 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3281 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3282 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3283 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3284 #if 1 3285 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3286 for (p = 0; p < 3; ++p) { 3287 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); 3288 } 3289 #endif 3290 supportNew[0] = (c - cStart)*8 + 1+4; 3291 supportNew[1] = (c - cStart)*8 + 3+4; 3292 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3293 #if 1 3294 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3295 for (p = 0; p < 2; ++p) { 3296 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); 3297 } 3298 #endif 3299 ++newp; 3300 /* Face H: {a, b, f} */ 3301 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3302 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3303 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3304 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3305 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3306 orntNew[2] = -2; 3307 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3308 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3309 #if 1 3310 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3311 for (p = 0; p < 3; ++p) { 3312 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); 3313 } 3314 #endif 3315 supportNew[0] = (c - cStart)*8 + 1+4; 3316 supportNew[1] = (c - cStart)*8 + 2+4; 3317 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3318 #if 1 3319 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3320 for (p = 0; p < 2; ++p) { 3321 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); 3322 } 3323 #endif 3324 ++newp; 3325 } 3326 /* Hybrid split faces have 4 edges and same cells */ 3327 for (f = fMax; f < fEnd; ++f) { 3328 const PetscInt *cone, *ornt, *support; 3329 PetscInt coneNew[4], orntNew[4]; 3330 PetscInt supportNew[2], size, s, c; 3331 3332 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3333 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3334 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3335 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3336 for (r = 0; r < 2; ++r) { 3337 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3338 3339 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3340 orntNew[0] = ornt[0]; 3341 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3342 orntNew[1] = ornt[1]; 3343 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3344 orntNew[2+r] = 0; 3345 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3346 orntNew[3-r] = 0; 3347 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3348 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3349 #if 1 3350 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3351 for (p = 0; p < 2; ++p) { 3352 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); 3353 } 3354 for (p = 2; p < 4; ++p) { 3355 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); 3356 } 3357 #endif 3358 for (s = 0; s < size; ++s) { 3359 const PetscInt *coneCell, *orntCell, *fornt; 3360 PetscInt o, of; 3361 3362 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3363 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3364 o = orntCell[0] < 0 ? -1 : 1; 3365 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3366 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3367 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3368 of = fornt[c-2] < 0 ? -1 : 1; 3369 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3370 } 3371 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3372 #if 1 3373 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3374 for (p = 0; p < size; ++p) { 3375 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); 3376 } 3377 #endif 3378 } 3379 } 3380 /* Hybrid cell faces have 4 edges and 2 cells */ 3381 for (c = cMax; c < cEnd; ++c) { 3382 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3383 const PetscInt *cone, *ornt; 3384 PetscInt coneNew[4], orntNew[4]; 3385 PetscInt supportNew[2]; 3386 3387 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3388 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3389 for (r = 0; r < 3; ++r) { 3390 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3391 orntNew[0] = 0; 3392 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3393 orntNew[1] = 0; 3394 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3395 orntNew[2] = 0; 3396 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3397 orntNew[3] = 0; 3398 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3399 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3400 #if 1 3401 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); 3402 for (p = 0; p < 2; ++p) { 3403 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); 3404 } 3405 for (p = 2; p < 4; ++p) { 3406 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); 3407 } 3408 #endif 3409 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3410 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3411 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3412 #if 1 3413 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); 3414 for (p = 0; p < 2; ++p) { 3415 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); 3416 } 3417 #endif 3418 } 3419 } 3420 /* Interior split edges have 2 vertices and the same faces as the parent */ 3421 for (e = eStart; e < eMax; ++e) { 3422 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3423 3424 for (r = 0; r < 2; ++r) { 3425 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3426 const PetscInt *cone, *ornt, *support; 3427 PetscInt coneNew[2], coneSize, c, supportSize, s; 3428 3429 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3430 coneNew[0] = vStartNew + (cone[0] - vStart); 3431 coneNew[1] = vStartNew + (cone[1] - vStart); 3432 coneNew[(r+1)%2] = newv; 3433 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3434 #if 1 3435 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3436 for (p = 0; p < 2; ++p) { 3437 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); 3438 } 3439 #endif 3440 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3441 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3442 for (s = 0; s < supportSize; ++s) { 3443 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3444 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3445 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3446 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3447 if (support[s] < fMax) { 3448 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3449 } else { 3450 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3451 } 3452 } 3453 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3454 #if 1 3455 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3456 for (p = 0; p < supportSize; ++p) { 3457 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); 3458 } 3459 #endif 3460 } 3461 } 3462 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3463 for (f = fStart; f < fMax; ++f) { 3464 const PetscInt *cone, *ornt, *support; 3465 PetscInt coneSize, supportSize, s; 3466 3467 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3468 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3469 for (r = 0; r < 3; ++r) { 3470 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3471 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3472 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3473 -1, -1, 1, 6, 0, 4, 3474 2, 5, 3, 4, -1, -1, 3475 -1, -1, 3, 6, 2, 7}; 3476 3477 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3478 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3479 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3480 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3481 #if 1 3482 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3483 for (p = 0; p < 2; ++p) { 3484 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); 3485 } 3486 #endif 3487 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3488 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3489 for (s = 0; s < supportSize; ++s) { 3490 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3491 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3492 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3493 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3494 if (support[s] < cMax) { 3495 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3496 er = GetTetSomethingInverse_Static(ornt[c], r); 3497 if (er == eint[c]) { 3498 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3499 } else { 3500 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3501 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3502 } 3503 } else { 3504 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 3505 } 3506 } 3507 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3508 #if 1 3509 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3510 for (p = 0; p < intFaces; ++p) { 3511 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); 3512 } 3513 #endif 3514 } 3515 } 3516 /* Interior cell edges have 2 vertices and 4 faces */ 3517 for (c = cStart; c < cMax; ++c) { 3518 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3519 const PetscInt *cone, *ornt, *fcone; 3520 PetscInt coneNew[2], supportNew[4], find; 3521 3522 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3523 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3524 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3525 find = GetTriEdge_Static(ornt[0], 0); 3526 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3527 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3528 find = GetTriEdge_Static(ornt[2], 1); 3529 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3530 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3531 #if 1 3532 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3533 for (p = 0; p < 2; ++p) { 3534 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); 3535 } 3536 #endif 3537 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3538 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3539 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3540 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3541 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3542 #if 1 3543 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3544 for (p = 0; p < 4; ++p) { 3545 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); 3546 } 3547 #endif 3548 } 3549 /* Hybrid edges have two vertices and the same faces */ 3550 for (e = eMax; e < eEnd; ++e) { 3551 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3552 const PetscInt *cone, *support, *fcone; 3553 PetscInt coneNew[2], size, fsize, s; 3554 3555 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3556 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3557 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3558 coneNew[0] = vStartNew + (cone[0] - vStart); 3559 coneNew[1] = vStartNew + (cone[1] - vStart); 3560 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3561 #if 1 3562 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3563 for (p = 0; p < 2; ++p) { 3564 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); 3565 } 3566 #endif 3567 for (s = 0; s < size; ++s) { 3568 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3569 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3570 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3571 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3572 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3573 } 3574 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3575 #if 1 3576 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3577 for (p = 0; p < size; ++p) { 3578 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); 3579 } 3580 #endif 3581 } 3582 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3583 for (f = fMax; f < fEnd; ++f) { 3584 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3585 const PetscInt *cone, *support, *ccone, *cornt; 3586 PetscInt coneNew[2], size, csize, s; 3587 3588 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3589 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3590 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3591 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3592 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3593 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3594 #if 1 3595 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3596 for (p = 0; p < 2; ++p) { 3597 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); 3598 } 3599 #endif 3600 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3601 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3602 for (s = 0; s < size; ++s) { 3603 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3604 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3605 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3606 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3607 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]); 3608 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 3609 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 3610 } 3611 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3612 #if 1 3613 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3614 for (p = 0; p < 2+size*2; ++p) { 3615 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); 3616 } 3617 #endif 3618 } 3619 /* Interior vertices have identical supports */ 3620 for (v = vStart; v < vEnd; ++v) { 3621 const PetscInt newp = vStartNew + (v - vStart); 3622 const PetscInt *support, *cone; 3623 PetscInt size, s; 3624 3625 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3626 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3627 for (s = 0; s < size; ++s) { 3628 PetscInt r = 0; 3629 3630 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3631 if (cone[1] == v) r = 1; 3632 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3633 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3634 } 3635 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3636 #if 1 3637 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3638 for (p = 0; p < size; ++p) { 3639 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); 3640 } 3641 #endif 3642 } 3643 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3644 for (e = eStart; e < eMax; ++e) { 3645 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3646 const PetscInt *cone, *support; 3647 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3648 3649 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3650 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3651 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3652 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3653 for (s = 0; s < size; ++s) { 3654 PetscInt r = 0; 3655 3656 if (support[s] < fMax) { 3657 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3658 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3659 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3660 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3661 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3662 faceSize += 2; 3663 } else { 3664 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3665 ++faceSize; 3666 } 3667 } 3668 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3669 for (s = 0; s < starSize*2; s += 2) { 3670 const PetscInt *cone, *ornt; 3671 PetscInt e01, e23; 3672 3673 if ((star[s] >= cStart) && (star[s] < cMax)) { 3674 /* Check edge 0-1 */ 3675 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3676 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3677 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3678 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3679 /* Check edge 2-3 */ 3680 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3681 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3682 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3683 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3684 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3685 } 3686 } 3687 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 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 < 2+faceSize+cellSize; ++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 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3697 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3698 break; 3699 case 6: 3700 /* Hex 3D */ 3701 /* 3702 Bottom (viewed from top) Top 3703 1---------2---------2 7---------2---------6 3704 | | | | | | 3705 | B 2 C | | H 2 G | 3706 | | | | | | 3707 3----3----0----1----1 3----3----0----1----1 3708 | | | | | | 3709 | A 0 D | | E 0 F | 3710 | | | | | | 3711 0---------0---------3 4---------0---------5 3712 */ 3713 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3714 for (c = cStart; c < cEnd; ++c) { 3715 const PetscInt newp = (c - cStart)*8; 3716 const PetscInt *cone, *ornt; 3717 PetscInt coneNew[6], orntNew[6]; 3718 3719 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3720 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3721 /* A hex */ 3722 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3723 orntNew[0] = ornt[0]; 3724 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3725 orntNew[1] = 0; 3726 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3727 orntNew[2] = ornt[2]; 3728 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3729 orntNew[3] = 0; 3730 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3731 orntNew[4] = 0; 3732 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3733 orntNew[5] = ornt[5]; 3734 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3735 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3736 #if 1 3737 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); 3738 for (p = 0; p < 6; ++p) { 3739 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); 3740 } 3741 #endif 3742 /* B hex */ 3743 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3744 orntNew[0] = ornt[0]; 3745 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3746 orntNew[1] = 0; 3747 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3748 orntNew[2] = -1; 3749 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3750 orntNew[3] = ornt[3]; 3751 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3752 orntNew[4] = 0; 3753 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3754 orntNew[5] = ornt[5]; 3755 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3756 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3757 #if 1 3758 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); 3759 for (p = 0; p < 6; ++p) { 3760 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); 3761 } 3762 #endif 3763 /* C hex */ 3764 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3765 orntNew[0] = ornt[0]; 3766 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3767 orntNew[1] = 0; 3768 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3769 orntNew[2] = -1; 3770 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3771 orntNew[3] = ornt[3]; 3772 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3773 orntNew[4] = ornt[4]; 3774 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3775 orntNew[5] = -4; 3776 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3777 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3778 #if 1 3779 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); 3780 for (p = 0; p < 6; ++p) { 3781 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); 3782 } 3783 #endif 3784 /* D hex */ 3785 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3786 orntNew[0] = ornt[0]; 3787 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3788 orntNew[1] = 0; 3789 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3790 orntNew[2] = ornt[2]; 3791 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3792 orntNew[3] = 0; 3793 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3794 orntNew[4] = ornt[4]; 3795 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3796 orntNew[5] = -4; 3797 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3798 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3799 #if 1 3800 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); 3801 for (p = 0; p < 6; ++p) { 3802 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); 3803 } 3804 #endif 3805 /* E hex */ 3806 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3807 orntNew[0] = -4; 3808 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3809 orntNew[1] = ornt[1]; 3810 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3811 orntNew[2] = ornt[2]; 3812 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3813 orntNew[3] = 0; 3814 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3815 orntNew[4] = -1; 3816 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3817 orntNew[5] = ornt[5]; 3818 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3819 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3820 #if 1 3821 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); 3822 for (p = 0; p < 6; ++p) { 3823 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); 3824 } 3825 #endif 3826 /* F hex */ 3827 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3828 orntNew[0] = -4; 3829 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3830 orntNew[1] = ornt[1]; 3831 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3832 orntNew[2] = ornt[2]; 3833 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3834 orntNew[3] = -1; 3835 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3836 orntNew[4] = ornt[4]; 3837 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3838 orntNew[5] = 1; 3839 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3840 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3841 #if 1 3842 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); 3843 for (p = 0; p < 6; ++p) { 3844 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); 3845 } 3846 #endif 3847 /* G hex */ 3848 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3849 orntNew[0] = -4; 3850 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3851 orntNew[1] = ornt[1]; 3852 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3853 orntNew[2] = 0; 3854 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3855 orntNew[3] = ornt[3]; 3856 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3857 orntNew[4] = ornt[4]; 3858 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3859 orntNew[5] = -3; 3860 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3861 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3862 #if 1 3863 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); 3864 for (p = 0; p < 6; ++p) { 3865 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); 3866 } 3867 #endif 3868 /* H hex */ 3869 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3870 orntNew[0] = -4; 3871 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3872 orntNew[1] = ornt[1]; 3873 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3874 orntNew[2] = -1; 3875 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3876 orntNew[3] = ornt[3]; 3877 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3878 orntNew[4] = 3; 3879 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3880 orntNew[5] = ornt[5]; 3881 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3882 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3883 #if 1 3884 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); 3885 for (p = 0; p < 6; ++p) { 3886 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); 3887 } 3888 #endif 3889 } 3890 /* Split faces have 4 edges and the same cells as the parent */ 3891 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3892 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 3893 for (f = fStart; f < fEnd; ++f) { 3894 for (r = 0; r < 4; ++r) { 3895 /* TODO: This can come from GetFaces_Internal() */ 3896 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}; 3897 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3898 const PetscInt *cone, *ornt, *support; 3899 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3900 3901 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3902 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3903 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3904 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3905 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3906 orntNew[(r+0)%4] = ornt[r]; 3907 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3908 orntNew[(r+1)%4] = 0; 3909 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3910 orntNew[(r+2)%4] = -2; 3911 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3912 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3913 #if 1 3914 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3915 for (p = 0; p < 4; ++p) { 3916 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); 3917 } 3918 #endif 3919 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3920 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3921 for (s = 0; s < supportSize; ++s) { 3922 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3923 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3924 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3925 for (c = 0; c < coneSize; ++c) { 3926 if (cone[c] == f) break; 3927 } 3928 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 3929 } 3930 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3931 #if 1 3932 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3933 for (p = 0; p < supportSize; ++p) { 3934 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); 3935 } 3936 #endif 3937 } 3938 } 3939 /* Interior faces have 4 edges and 2 cells */ 3940 for (c = cStart; c < cEnd; ++c) { 3941 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}; 3942 const PetscInt *cone, *ornt; 3943 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 3944 3945 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3946 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3947 /* A-D face */ 3948 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 3949 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 3950 orntNew[0] = 0; 3951 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3952 orntNew[1] = 0; 3953 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 3954 orntNew[2] = -2; 3955 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 3956 orntNew[3] = -2; 3957 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3958 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3959 #if 1 3960 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3961 for (p = 0; p < 4; ++p) { 3962 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); 3963 } 3964 #endif 3965 /* C-D face */ 3966 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 3967 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 3968 orntNew[0] = 0; 3969 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3970 orntNew[1] = 0; 3971 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 3972 orntNew[2] = -2; 3973 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 3974 orntNew[3] = -2; 3975 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3976 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3977 #if 1 3978 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3979 for (p = 0; p < 4; ++p) { 3980 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); 3981 } 3982 #endif 3983 /* B-C face */ 3984 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 3985 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 3986 orntNew[0] = -2; 3987 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 3988 orntNew[1] = 0; 3989 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 3990 orntNew[2] = 0; 3991 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 3992 orntNew[3] = -2; 3993 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3994 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3995 #if 1 3996 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3997 for (p = 0; p < 4; ++p) { 3998 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); 3999 } 4000 #endif 4001 /* A-B face */ 4002 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 4003 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4004 orntNew[0] = -2; 4005 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4006 orntNew[1] = 0; 4007 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4008 orntNew[2] = 0; 4009 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4010 orntNew[3] = -2; 4011 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4012 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4013 #if 1 4014 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4015 for (p = 0; p < 4; ++p) { 4016 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); 4017 } 4018 #endif 4019 /* E-F face */ 4020 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 4021 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4022 orntNew[0] = -2; 4023 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4024 orntNew[1] = -2; 4025 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4026 orntNew[2] = 0; 4027 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4028 orntNew[3] = 0; 4029 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4030 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4031 #if 1 4032 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4033 for (p = 0; p < 4; ++p) { 4034 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); 4035 } 4036 #endif 4037 /* F-G face */ 4038 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 4039 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4040 orntNew[0] = -2; 4041 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4042 orntNew[1] = -2; 4043 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4044 orntNew[2] = 0; 4045 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4046 orntNew[3] = 0; 4047 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4048 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4049 #if 1 4050 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4051 for (p = 0; p < 4; ++p) { 4052 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); 4053 } 4054 #endif 4055 /* G-H face */ 4056 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 4057 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4058 orntNew[0] = -2; 4059 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4060 orntNew[1] = 0; 4061 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4062 orntNew[2] = 0; 4063 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4064 orntNew[3] = -2; 4065 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4066 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4067 #if 1 4068 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4069 for (p = 0; p < 4; ++p) { 4070 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); 4071 } 4072 #endif 4073 /* E-H face */ 4074 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 4075 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4076 orntNew[0] = -2; 4077 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4078 orntNew[1] = -2; 4079 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4080 orntNew[2] = 0; 4081 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4082 orntNew[3] = 0; 4083 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4084 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4085 #if 1 4086 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4087 for (p = 0; p < 4; ++p) { 4088 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); 4089 } 4090 #endif 4091 /* A-E face */ 4092 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 4093 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4094 orntNew[0] = 0; 4095 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4096 orntNew[1] = 0; 4097 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4098 orntNew[2] = -2; 4099 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4100 orntNew[3] = -2; 4101 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4102 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4103 #if 1 4104 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4105 for (p = 0; p < 4; ++p) { 4106 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); 4107 } 4108 #endif 4109 /* D-F face */ 4110 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 4111 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4112 orntNew[0] = -2; 4113 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4114 orntNew[1] = 0; 4115 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4116 orntNew[2] = 0; 4117 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4118 orntNew[3] = -2; 4119 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4120 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4121 #if 1 4122 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4123 for (p = 0; p < 4; ++p) { 4124 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); 4125 } 4126 #endif 4127 /* C-G face */ 4128 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 4129 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4130 orntNew[0] = -2; 4131 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4132 orntNew[1] = -2; 4133 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4134 orntNew[2] = 0; 4135 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4136 orntNew[3] = 0; 4137 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4138 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4139 #if 1 4140 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4141 for (p = 0; p < 4; ++p) { 4142 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); 4143 } 4144 #endif 4145 /* B-H face */ 4146 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 4147 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4148 orntNew[0] = 0; 4149 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4150 orntNew[1] = -2; 4151 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4152 orntNew[2] = -2; 4153 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4154 orntNew[3] = 0; 4155 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4156 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4157 #if 1 4158 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4159 for (p = 0; p < 4; ++p) { 4160 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); 4161 } 4162 #endif 4163 for (r = 0; r < 12; ++r) { 4164 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 4165 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4166 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4167 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4168 #if 1 4169 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4170 for (p = 0; p < 2; ++p) { 4171 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); 4172 } 4173 #endif 4174 } 4175 } 4176 /* Split edges have 2 vertices and the same faces as the parent */ 4177 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4178 for (e = eStart; e < eEnd; ++e) { 4179 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4180 4181 for (r = 0; r < 2; ++r) { 4182 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4183 const PetscInt *cone, *ornt, *support; 4184 PetscInt coneNew[2], coneSize, c, supportSize, s; 4185 4186 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4187 coneNew[0] = vStartNew + (cone[0] - vStart); 4188 coneNew[1] = vStartNew + (cone[1] - vStart); 4189 coneNew[(r+1)%2] = newv; 4190 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4191 #if 1 4192 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4193 for (p = 0; p < 2; ++p) { 4194 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); 4195 } 4196 #endif 4197 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4198 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4199 for (s = 0; s < supportSize; ++s) { 4200 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4201 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4202 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4203 for (c = 0; c < coneSize; ++c) { 4204 if (cone[c] == e) break; 4205 } 4206 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 4207 } 4208 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4209 #if 1 4210 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4211 for (p = 0; p < supportSize; ++p) { 4212 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); 4213 } 4214 #endif 4215 } 4216 } 4217 /* Face edges have 2 vertices and 2+cells faces */ 4218 for (f = fStart; f < fEnd; ++f) { 4219 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}; 4220 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4221 const PetscInt *cone, *coneCell, *orntCell, *support; 4222 PetscInt coneNew[2], coneSize, c, supportSize, s; 4223 4224 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4225 for (r = 0; r < 4; ++r) { 4226 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4227 4228 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4229 coneNew[1] = newv; 4230 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4231 #if 1 4232 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4233 for (p = 0; p < 2; ++p) { 4234 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); 4235 } 4236 #endif 4237 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4238 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4239 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4240 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4241 for (s = 0; s < supportSize; ++s) { 4242 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4243 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4244 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4245 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4246 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4247 } 4248 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4249 #if 1 4250 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4251 for (p = 0; p < 2+supportSize; ++p) { 4252 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); 4253 } 4254 #endif 4255 } 4256 } 4257 /* Cell edges have 2 vertices and 4 faces */ 4258 for (c = cStart; c < cEnd; ++c) { 4259 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}; 4260 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4261 const PetscInt *cone; 4262 PetscInt coneNew[2], supportNew[4]; 4263 4264 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4265 for (r = 0; r < 6; ++r) { 4266 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4267 4268 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4269 coneNew[1] = newv; 4270 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4271 #if 1 4272 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4273 for (p = 0; p < 2; ++p) { 4274 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); 4275 } 4276 #endif 4277 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4278 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4279 #if 1 4280 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4281 for (p = 0; p < 4; ++p) { 4282 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); 4283 } 4284 #endif 4285 } 4286 } 4287 /* Old vertices have identical supports */ 4288 for (v = vStart; v < vEnd; ++v) { 4289 const PetscInt newp = vStartNew + (v - vStart); 4290 const PetscInt *support, *cone; 4291 PetscInt size, s; 4292 4293 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4294 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4295 for (s = 0; s < size; ++s) { 4296 PetscInt r = 0; 4297 4298 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4299 if (cone[1] == v) r = 1; 4300 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4301 } 4302 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4303 #if 1 4304 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4305 for (p = 0; p < size; ++p) { 4306 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); 4307 } 4308 #endif 4309 } 4310 /* Edge vertices have 2 + faces supports */ 4311 for (e = eStart; e < eEnd; ++e) { 4312 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4313 const PetscInt *cone, *support; 4314 PetscInt size, s; 4315 4316 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4317 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4318 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4319 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4320 for (s = 0; s < size; ++s) { 4321 PetscInt r; 4322 4323 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4324 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4325 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 4326 } 4327 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4328 #if 1 4329 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4330 for (p = 0; p < 2+size; ++p) { 4331 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); 4332 } 4333 #endif 4334 } 4335 /* Face vertices have 4 + cells supports */ 4336 for (f = fStart; f < fEnd; ++f) { 4337 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4338 const PetscInt *cone, *support; 4339 PetscInt size, s; 4340 4341 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4342 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4343 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4344 for (s = 0; s < size; ++s) { 4345 PetscInt r; 4346 4347 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4348 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4349 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 4350 } 4351 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4352 #if 1 4353 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4354 for (p = 0; p < 4+size; ++p) { 4355 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); 4356 } 4357 #endif 4358 } 4359 /* Cell vertices have 6 supports */ 4360 for (c = cStart; c < cEnd; ++c) { 4361 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4362 PetscInt supportNew[6]; 4363 4364 for (r = 0; r < 6; ++r) { 4365 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4366 } 4367 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4368 } 4369 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4370 break; 4371 case 8: 4372 /* Hybrid Hex 3D */ 4373 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4374 /* 4375 Bottom (viewed from top) Top 4376 1---------2---------2 7---------2---------6 4377 | | | | | | 4378 | B 2 C | | H 2 G | 4379 | | | | | | 4380 3----3----0----1----1 3----3----0----1----1 4381 | | | | | | 4382 | A 0 D | | E 0 F | 4383 | | | | | | 4384 0---------0---------3 4---------0---------5 4385 */ 4386 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4387 for (c = cStart; c < cMax; ++c) { 4388 const PetscInt newp = (c - cStart)*8; 4389 const PetscInt *cone, *ornt; 4390 PetscInt coneNew[6], orntNew[6]; 4391 4392 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4393 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4394 /* A hex */ 4395 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4396 orntNew[0] = ornt[0]; 4397 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4398 orntNew[1] = 0; 4399 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4400 orntNew[2] = ornt[2]; 4401 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4402 orntNew[3] = 0; 4403 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4404 orntNew[4] = 0; 4405 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4406 orntNew[5] = ornt[5]; 4407 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4408 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4409 #if 1 4410 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); 4411 for (p = 0; p < 6; ++p) { 4412 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); 4413 } 4414 #endif 4415 /* B hex */ 4416 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4417 orntNew[0] = ornt[0]; 4418 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4419 orntNew[1] = 0; 4420 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4421 orntNew[2] = -1; 4422 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4423 orntNew[3] = ornt[3]; 4424 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4425 orntNew[4] = 0; 4426 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4427 orntNew[5] = ornt[5]; 4428 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4429 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4430 #if 1 4431 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); 4432 for (p = 0; p < 6; ++p) { 4433 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); 4434 } 4435 #endif 4436 /* C hex */ 4437 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4438 orntNew[0] = ornt[0]; 4439 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4440 orntNew[1] = 0; 4441 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4442 orntNew[2] = -1; 4443 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4444 orntNew[3] = ornt[3]; 4445 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4446 orntNew[4] = ornt[4]; 4447 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4448 orntNew[5] = -4; 4449 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4450 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4451 #if 1 4452 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); 4453 for (p = 0; p < 6; ++p) { 4454 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); 4455 } 4456 #endif 4457 /* D hex */ 4458 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4459 orntNew[0] = ornt[0]; 4460 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4461 orntNew[1] = 0; 4462 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4463 orntNew[2] = ornt[2]; 4464 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4465 orntNew[3] = 0; 4466 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4467 orntNew[4] = ornt[4]; 4468 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4469 orntNew[5] = -4; 4470 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4471 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4472 #if 1 4473 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); 4474 for (p = 0; p < 6; ++p) { 4475 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); 4476 } 4477 #endif 4478 /* E hex */ 4479 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4480 orntNew[0] = -4; 4481 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4482 orntNew[1] = ornt[1]; 4483 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4484 orntNew[2] = ornt[2]; 4485 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4486 orntNew[3] = 0; 4487 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4488 orntNew[4] = -1; 4489 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4490 orntNew[5] = ornt[5]; 4491 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4492 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4493 #if 1 4494 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); 4495 for (p = 0; p < 6; ++p) { 4496 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); 4497 } 4498 #endif 4499 /* F hex */ 4500 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4501 orntNew[0] = -4; 4502 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4503 orntNew[1] = ornt[1]; 4504 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4505 orntNew[2] = ornt[2]; 4506 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4507 orntNew[3] = -1; 4508 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4509 orntNew[4] = ornt[4]; 4510 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4511 orntNew[5] = 1; 4512 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4513 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4514 #if 1 4515 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); 4516 for (p = 0; p < 6; ++p) { 4517 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); 4518 } 4519 #endif 4520 /* G hex */ 4521 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4522 orntNew[0] = -4; 4523 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4524 orntNew[1] = ornt[1]; 4525 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4526 orntNew[2] = 0; 4527 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4528 orntNew[3] = ornt[3]; 4529 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4530 orntNew[4] = ornt[4]; 4531 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4532 orntNew[5] = -3; 4533 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4534 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4535 #if 1 4536 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); 4537 for (p = 0; p < 6; ++p) { 4538 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); 4539 } 4540 #endif 4541 /* H hex */ 4542 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4543 orntNew[0] = -4; 4544 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4545 orntNew[1] = ornt[1]; 4546 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4547 orntNew[2] = -1; 4548 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4549 orntNew[3] = ornt[3]; 4550 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4551 orntNew[4] = 3; 4552 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4553 orntNew[5] = ornt[5]; 4554 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4555 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4556 #if 1 4557 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); 4558 for (p = 0; p < 6; ++p) { 4559 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); 4560 } 4561 #endif 4562 } 4563 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4564 /* 4565 3---------2---------2 4566 | | | 4567 | D 2 C | 4568 | | | 4569 3----3----0----1----1 4570 | | | 4571 | A 0 B | 4572 | | | 4573 0---------0---------1 4574 */ 4575 for (c = cMax; c < cEnd; ++c) { 4576 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4577 const PetscInt *cone, *ornt, *fornt; 4578 PetscInt coneNew[6], orntNew[6], o, of, i; 4579 4580 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4581 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4582 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4583 o = ornt[0] < 0 ? -1 : 1; 4584 for (r = 0; r < 4; ++r) { 4585 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4586 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4587 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 4588 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]); 4589 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4590 orntNew[0] = ornt[0]; 4591 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4592 orntNew[1] = ornt[0]; 4593 of = fornt[edgeA] < 0 ? -1 : 1; 4594 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 4595 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 4596 orntNew[i] = ornt[edgeA]; 4597 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 4598 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4599 orntNew[i] = 0; 4600 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 4601 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4602 orntNew[i] = -2; 4603 of = fornt[edgeB] < 0 ? -1 : 1; 4604 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 4605 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 4606 orntNew[i] = ornt[edgeB]; 4607 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4608 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4609 #if 1 4610 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); 4611 for (p = 0; p < 2; ++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 for (p = 2; p < 6; ++p) { 4615 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); 4616 } 4617 #endif 4618 } 4619 } 4620 /* Interior split faces have 4 edges and the same cells as the parent */ 4621 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4622 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 4623 for (f = fStart; f < fMax; ++f) { 4624 for (r = 0; r < 4; ++r) { 4625 /* TODO: This can come from GetFaces_Internal() */ 4626 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}; 4627 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4628 const PetscInt *cone, *ornt, *support; 4629 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4630 4631 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4632 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4633 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4634 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4635 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4636 orntNew[(r+0)%4] = ornt[r]; 4637 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4638 orntNew[(r+1)%4] = 0; 4639 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4640 orntNew[(r+2)%4] = -2; 4641 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4642 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4643 #if 1 4644 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4645 for (p = 0; p < 4; ++p) { 4646 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); 4647 } 4648 #endif 4649 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4650 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4651 for (s = 0; s < supportSize; ++s) { 4652 PetscInt subf; 4653 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4654 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4655 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4656 for (c = 0; c < coneSize; ++c) { 4657 if (cone[c] == f) break; 4658 } 4659 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4660 if (support[s] < cMax) { 4661 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4662 } else { 4663 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4664 } 4665 } 4666 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4667 #if 1 4668 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4669 for (p = 0; p < supportSize; ++p) { 4670 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); 4671 } 4672 #endif 4673 } 4674 } 4675 /* Interior cell faces have 4 edges and 2 cells */ 4676 for (c = cStart; c < cMax; ++c) { 4677 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}; 4678 const PetscInt *cone, *ornt; 4679 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4680 4681 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4682 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4683 /* A-D face */ 4684 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4685 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4686 orntNew[0] = 0; 4687 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4688 orntNew[1] = 0; 4689 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4690 orntNew[2] = -2; 4691 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4692 orntNew[3] = -2; 4693 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4694 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4695 #if 1 4696 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4697 for (p = 0; p < 4; ++p) { 4698 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); 4699 } 4700 #endif 4701 /* C-D face */ 4702 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4703 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4704 orntNew[0] = 0; 4705 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4706 orntNew[1] = 0; 4707 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4708 orntNew[2] = -2; 4709 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4710 orntNew[3] = -2; 4711 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4712 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4713 #if 1 4714 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4715 for (p = 0; p < 4; ++p) { 4716 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); 4717 } 4718 #endif 4719 /* B-C face */ 4720 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4721 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4722 orntNew[0] = -2; 4723 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4724 orntNew[1] = 0; 4725 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4726 orntNew[2] = 0; 4727 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4728 orntNew[3] = -2; 4729 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4730 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4731 #if 1 4732 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4733 for (p = 0; p < 4; ++p) { 4734 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); 4735 } 4736 #endif 4737 /* A-B face */ 4738 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4739 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4740 orntNew[0] = -2; 4741 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4742 orntNew[1] = 0; 4743 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4744 orntNew[2] = 0; 4745 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4746 orntNew[3] = -2; 4747 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4748 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4749 #if 1 4750 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4751 for (p = 0; p < 4; ++p) { 4752 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); 4753 } 4754 #endif 4755 /* E-F face */ 4756 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4757 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4758 orntNew[0] = -2; 4759 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4760 orntNew[1] = -2; 4761 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4762 orntNew[2] = 0; 4763 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4764 orntNew[3] = 0; 4765 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4766 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4767 #if 1 4768 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4769 for (p = 0; p < 4; ++p) { 4770 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); 4771 } 4772 #endif 4773 /* F-G face */ 4774 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4775 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4776 orntNew[0] = -2; 4777 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4778 orntNew[1] = -2; 4779 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4780 orntNew[2] = 0; 4781 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4782 orntNew[3] = 0; 4783 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4784 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4785 #if 1 4786 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4787 for (p = 0; p < 4; ++p) { 4788 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); 4789 } 4790 #endif 4791 /* G-H face */ 4792 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4793 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4794 orntNew[0] = -2; 4795 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4796 orntNew[1] = 0; 4797 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4798 orntNew[2] = 0; 4799 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4800 orntNew[3] = -2; 4801 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4802 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4803 #if 1 4804 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4805 for (p = 0; p < 4; ++p) { 4806 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); 4807 } 4808 #endif 4809 /* E-H face */ 4810 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4811 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4812 orntNew[0] = -2; 4813 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4814 orntNew[1] = -2; 4815 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4816 orntNew[2] = 0; 4817 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4818 orntNew[3] = 0; 4819 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4820 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4821 #if 1 4822 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4823 for (p = 0; p < 4; ++p) { 4824 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); 4825 } 4826 #endif 4827 /* A-E face */ 4828 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4829 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4830 orntNew[0] = 0; 4831 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4832 orntNew[1] = 0; 4833 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4834 orntNew[2] = -2; 4835 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4836 orntNew[3] = -2; 4837 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4838 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4839 #if 1 4840 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4841 for (p = 0; p < 4; ++p) { 4842 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); 4843 } 4844 #endif 4845 /* D-F face */ 4846 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4847 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4848 orntNew[0] = -2; 4849 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4850 orntNew[1] = 0; 4851 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4852 orntNew[2] = 0; 4853 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4854 orntNew[3] = -2; 4855 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4856 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4857 #if 1 4858 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4859 for (p = 0; p < 4; ++p) { 4860 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); 4861 } 4862 #endif 4863 /* C-G face */ 4864 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4865 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4866 orntNew[0] = -2; 4867 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4868 orntNew[1] = -2; 4869 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4870 orntNew[2] = 0; 4871 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4872 orntNew[3] = 0; 4873 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4874 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4875 #if 1 4876 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4877 for (p = 0; p < 4; ++p) { 4878 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); 4879 } 4880 #endif 4881 /* B-H face */ 4882 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 4883 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4884 orntNew[0] = 0; 4885 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4886 orntNew[1] = -2; 4887 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4888 orntNew[2] = -2; 4889 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4890 orntNew[3] = 0; 4891 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4892 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4893 #if 1 4894 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4895 for (p = 0; p < 4; ++p) { 4896 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); 4897 } 4898 #endif 4899 for (r = 0; r < 12; ++r) { 4900 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 4901 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4902 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4903 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4904 #if 1 4905 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4906 for (p = 0; p < 2; ++p) { 4907 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); 4908 } 4909 #endif 4910 } 4911 } 4912 /* Hybrid split faces have 4 edges and same cells */ 4913 for (f = fMax; f < fEnd; ++f) { 4914 const PetscInt *cone, *ornt, *support; 4915 PetscInt coneNew[4], orntNew[4]; 4916 PetscInt supportNew[2], size, s, c; 4917 4918 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4919 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4920 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4921 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4922 for (r = 0; r < 2; ++r) { 4923 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 4924 4925 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4926 orntNew[0] = ornt[0]; 4927 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4928 orntNew[1] = ornt[1]; 4929 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 4930 orntNew[2+r] = 0; 4931 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4932 orntNew[3-r] = 0; 4933 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4934 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4935 #if 1 4936 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4937 for (p = 0; p < 2; ++p) { 4938 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); 4939 } 4940 for (p = 2; p < 4; ++p) { 4941 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); 4942 } 4943 #endif 4944 for (s = 0; s < size; ++s) { 4945 const PetscInt *coneCell, *orntCell, *fornt; 4946 PetscInt o, of; 4947 4948 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4949 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4950 o = orntCell[0] < 0 ? -1 : 1; 4951 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 4952 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 4953 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4954 of = fornt[c-2] < 0 ? -1 : 1; 4955 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 4956 } 4957 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4958 #if 1 4959 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4960 for (p = 0; p < size; ++p) { 4961 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); 4962 } 4963 #endif 4964 } 4965 } 4966 /* Hybrid cell faces have 4 edges and 2 cells */ 4967 for (c = cMax; c < cEnd; ++c) { 4968 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 4969 const PetscInt *cone, *ornt; 4970 PetscInt coneNew[4], orntNew[4]; 4971 PetscInt supportNew[2]; 4972 4973 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4974 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4975 for (r = 0; r < 4; ++r) { 4976 #if 0 4977 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 4978 orntNew[0] = 0; 4979 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 4980 orntNew[1] = 0; 4981 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 4982 orntNew[2] = 0; 4983 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4984 orntNew[3] = 0; 4985 #else 4986 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 4987 orntNew[0] = 0; 4988 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 4989 orntNew[1] = 0; 4990 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 4991 orntNew[2] = 0; 4992 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4993 orntNew[3] = 0; 4994 #endif 4995 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4996 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4997 #if 1 4998 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); 4999 for (p = 0; p < 2; ++p) { 5000 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); 5001 } 5002 for (p = 2; p < 4; ++p) { 5003 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); 5004 } 5005 #endif 5006 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 5007 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 5008 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 5009 #if 1 5010 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); 5011 for (p = 0; p < 2; ++p) { 5012 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); 5013 } 5014 #endif 5015 } 5016 } 5017 /* Interior split edges have 2 vertices and the same faces as the parent */ 5018 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5019 for (e = eStart; e < eMax; ++e) { 5020 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5021 5022 for (r = 0; r < 2; ++r) { 5023 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5024 const PetscInt *cone, *ornt, *support; 5025 PetscInt coneNew[2], coneSize, c, supportSize, s; 5026 5027 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5028 coneNew[0] = vStartNew + (cone[0] - vStart); 5029 coneNew[1] = vStartNew + (cone[1] - vStart); 5030 coneNew[(r+1)%2] = newv; 5031 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5032 #if 1 5033 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5034 for (p = 0; p < 2; ++p) { 5035 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); 5036 } 5037 #endif 5038 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5039 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5040 for (s = 0; s < supportSize; ++s) { 5041 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5042 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5043 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5044 for (c = 0; c < coneSize; ++c) { 5045 if (cone[c] == e) break; 5046 } 5047 if (support[s] < fMax) { 5048 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 5049 } else { 5050 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 5051 } 5052 } 5053 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5054 #if 1 5055 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5056 for (p = 0; p < supportSize; ++p) { 5057 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); 5058 } 5059 #endif 5060 } 5061 } 5062 /* Interior face edges have 2 vertices and 2+cells faces */ 5063 for (f = fStart; f < fMax; ++f) { 5064 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}; 5065 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5066 const PetscInt *cone, *coneCell, *orntCell, *support; 5067 PetscInt coneNew[2], coneSize, c, supportSize, s; 5068 5069 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5070 for (r = 0; r < 4; ++r) { 5071 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5072 5073 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5074 coneNew[1] = newv; 5075 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5076 #if 1 5077 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5078 for (p = 0; p < 2; ++p) { 5079 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); 5080 } 5081 #endif 5082 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5083 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5084 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5085 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5086 for (s = 0; s < supportSize; ++s) { 5087 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5088 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5089 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5090 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5091 if (support[s] < cMax) { 5092 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5093 } else { 5094 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 5095 } 5096 } 5097 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5098 #if 1 5099 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5100 for (p = 0; p < 2+supportSize; ++p) { 5101 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); 5102 } 5103 #endif 5104 } 5105 } 5106 /* Interior cell edges have 2 vertices and 4 faces */ 5107 for (c = cStart; c < cMax; ++c) { 5108 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}; 5109 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5110 const PetscInt *cone; 5111 PetscInt coneNew[2], supportNew[4]; 5112 5113 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5114 for (r = 0; r < 6; ++r) { 5115 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5116 5117 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5118 coneNew[1] = newv; 5119 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5120 #if 1 5121 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5122 for (p = 0; p < 2; ++p) { 5123 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); 5124 } 5125 #endif 5126 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5127 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5128 #if 1 5129 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5130 for (p = 0; p < 4; ++p) { 5131 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); 5132 } 5133 #endif 5134 } 5135 } 5136 /* Hybrid edges have two vertices and the same faces */ 5137 for (e = eMax; e < eEnd; ++e) { 5138 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5139 const PetscInt *cone, *support, *fcone; 5140 PetscInt coneNew[2], size, fsize, s; 5141 5142 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5143 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5144 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5145 coneNew[0] = vStartNew + (cone[0] - vStart); 5146 coneNew[1] = vStartNew + (cone[1] - vStart); 5147 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5148 #if 1 5149 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5150 for (p = 0; p < 2; ++p) { 5151 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); 5152 } 5153 #endif 5154 for (s = 0; s < size; ++s) { 5155 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5156 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5157 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5158 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5159 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 5160 } 5161 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5162 #if 1 5163 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5164 for (p = 0; p < size; ++p) { 5165 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); 5166 } 5167 #endif 5168 } 5169 /* Hybrid face edges have 2 vertices and 2+cells faces */ 5170 for (f = fMax; f < fEnd; ++f) { 5171 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5172 const PetscInt *cone, *support, *ccone, *cornt; 5173 PetscInt coneNew[2], size, csize, s; 5174 5175 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5176 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5177 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5178 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5179 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 5180 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5181 #if 1 5182 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5183 for (p = 0; p < 2; ++p) { 5184 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); 5185 } 5186 #endif 5187 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 5188 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5189 for (s = 0; s < size; ++s) { 5190 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5191 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5192 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5193 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5194 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]); 5195 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 5196 } 5197 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5198 #if 1 5199 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5200 for (p = 0; p < 2+size; ++p) { 5201 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); 5202 } 5203 #endif 5204 } 5205 /* Hybrid cell edges have 2 vertices and 4 faces */ 5206 for (c = cMax; c < cEnd; ++c) { 5207 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5208 const PetscInt *cone, *support; 5209 PetscInt coneNew[2], size; 5210 5211 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5212 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5213 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5214 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5215 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5216 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5217 #if 1 5218 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5219 for (p = 0; p < 2; ++p) { 5220 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); 5221 } 5222 #endif 5223 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5224 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5225 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5226 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5227 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5228 #if 1 5229 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5230 for (p = 0; p < 4; ++p) { 5231 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); 5232 } 5233 #endif 5234 } 5235 /* Interior vertices have identical supports */ 5236 for (v = vStart; v < vEnd; ++v) { 5237 const PetscInt newp = vStartNew + (v - vStart); 5238 const PetscInt *support, *cone; 5239 PetscInt size, s; 5240 5241 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5242 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5243 for (s = 0; s < size; ++s) { 5244 PetscInt r = 0; 5245 5246 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5247 if (cone[1] == v) r = 1; 5248 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5249 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5250 } 5251 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5252 #if 1 5253 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5254 for (p = 0; p < size; ++p) { 5255 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); 5256 } 5257 #endif 5258 } 5259 /* Interior edge vertices have 2 + faces supports */ 5260 for (e = eStart; e < eMax; ++e) { 5261 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5262 const PetscInt *cone, *support; 5263 PetscInt size, s; 5264 5265 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5266 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5267 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5268 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5269 for (s = 0; s < size; ++s) { 5270 PetscInt r; 5271 5272 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5273 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5274 if (support[s] < fMax) { 5275 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5276 } else { 5277 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5278 } 5279 } 5280 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5281 #if 1 5282 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5283 for (p = 0; p < 2+size; ++p) { 5284 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); 5285 } 5286 #endif 5287 } 5288 /* Interior face vertices have 4 + cells supports */ 5289 for (f = fStart; f < fMax; ++f) { 5290 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5291 const PetscInt *cone, *support; 5292 PetscInt size, s; 5293 5294 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5295 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5296 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5297 for (s = 0; s < size; ++s) { 5298 PetscInt r; 5299 5300 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5301 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5302 if (support[s] < cMax) { 5303 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5304 } else { 5305 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5306 } 5307 } 5308 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5309 #if 1 5310 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5311 for (p = 0; p < 4+size; ++p) { 5312 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); 5313 } 5314 #endif 5315 } 5316 /* Cell vertices have 6 supports */ 5317 for (c = cStart; c < cMax; ++c) { 5318 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5319 PetscInt supportNew[6]; 5320 5321 for (r = 0; r < 6; ++r) { 5322 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5323 } 5324 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5325 } 5326 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5327 break; 5328 default: 5329 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5330 } 5331 PetscFunctionReturn(0); 5332 } 5333 5334 #undef __FUNCT__ 5335 #define __FUNCT__ "CellRefinerSetCoordinates" 5336 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5337 { 5338 PetscSection coordSection, coordSectionNew; 5339 Vec coordinates, coordinatesNew; 5340 PetscScalar *coords, *coordsNew; 5341 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5342 PetscInt dim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5343 PetscErrorCode ierr; 5344 5345 PetscFunctionBegin; 5346 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 5347 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5348 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5349 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5350 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5351 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5352 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5353 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5354 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5355 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5356 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5357 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5358 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 5359 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5360 if (cMax < 0) cMax = cEnd; 5361 if (fMax < 0) fMax = fEnd; 5362 if (eMax < 0) eMax = eEnd; 5363 /* All vertices have the dim coordinates */ 5364 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5365 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 5366 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 5367 } 5368 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5369 ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 5370 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5371 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5372 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 5373 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5374 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5375 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 5376 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 5377 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 5378 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5379 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5380 switch (refiner) { 5381 case 0: break; 5382 case 6: /* Hex 3D */ 5383 case 8: /* Hybrid Hex 3D */ 5384 /* Face vertices have the average of corner coordinates */ 5385 for (f = fStart; f < fMax; ++f) { 5386 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5387 PetscInt *cone = NULL; 5388 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5389 5390 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5391 for (p = 0; p < closureSize*2; p += 2) { 5392 const PetscInt point = cone[p]; 5393 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5394 } 5395 for (v = 0; v < coneSize; ++v) { 5396 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5397 } 5398 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5399 for (d = 0; d < dim; ++d) { 5400 coordsNew[offnew+d] = 0.0; 5401 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5402 coordsNew[offnew+d] /= coneSize; 5403 } 5404 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5405 } 5406 case 2: /* Hex 2D */ 5407 case 4: /* Hybrid Hex 2D */ 5408 /* Cell vertices have the average of corner coordinates */ 5409 for (c = cStart; c < cMax; ++c) { 5410 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 5411 PetscInt *cone = NULL; 5412 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5413 5414 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5415 for (p = 0; p < closureSize*2; p += 2) { 5416 const PetscInt point = cone[p]; 5417 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5418 } 5419 for (v = 0; v < coneSize; ++v) { 5420 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5421 } 5422 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5423 for (d = 0; d < dim; ++d) { 5424 coordsNew[offnew+d] = 0.0; 5425 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5426 coordsNew[offnew+d] /= coneSize; 5427 } 5428 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5429 } 5430 case 1: /* Simplicial 2D */ 5431 case 3: /* Hybrid Simplicial 2D */ 5432 case 5: /* Simplicial 3D */ 5433 case 7: /* Hybrid Simplicial 3D */ 5434 /* Edge vertices have the average of endpoint coordinates */ 5435 for (e = eStart; e < eMax; ++e) { 5436 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5437 const PetscInt *cone; 5438 PetscInt coneSize, offA, offB, offnew, d; 5439 5440 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5441 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5442 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5443 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5444 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5445 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5446 for (d = 0; d < dim; ++d) { 5447 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 5448 } 5449 } 5450 /* Old vertices have the same coordinates */ 5451 for (v = vStart; v < vEnd; ++v) { 5452 const PetscInt newv = vStartNew + (v - vStart); 5453 PetscInt off, offnew, d; 5454 5455 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5456 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5457 for (d = 0; d < dim; ++d) { 5458 coordsNew[offnew+d] = coords[off+d]; 5459 } 5460 } 5461 break; 5462 default: 5463 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5464 } 5465 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5466 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5467 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5468 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5469 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5470 PetscFunctionReturn(0); 5471 } 5472 5473 #undef __FUNCT__ 5474 #define __FUNCT__ "DMPlexCreateProcessSF" 5475 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5476 { 5477 PetscInt numRoots, numLeaves, l; 5478 const PetscInt *localPoints; 5479 const PetscSFNode *remotePoints; 5480 PetscInt *localPointsNew; 5481 PetscSFNode *remotePointsNew; 5482 PetscInt *ranks, *ranksNew; 5483 PetscErrorCode ierr; 5484 5485 PetscFunctionBegin; 5486 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5487 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5488 for (l = 0; l < numLeaves; ++l) { 5489 ranks[l] = remotePoints[l].rank; 5490 } 5491 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5492 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5493 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5494 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5495 for (l = 0; l < numLeaves; ++l) { 5496 ranksNew[l] = ranks[l]; 5497 localPointsNew[l] = l; 5498 remotePointsNew[l].index = 0; 5499 remotePointsNew[l].rank = ranksNew[l]; 5500 } 5501 ierr = PetscFree(ranks);CHKERRQ(ierr); 5502 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 5503 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5504 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5505 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5506 PetscFunctionReturn(0); 5507 } 5508 5509 #undef __FUNCT__ 5510 #define __FUNCT__ "CellRefinerCreateSF" 5511 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5512 { 5513 PetscSF sf, sfNew, sfProcess; 5514 IS processRanks; 5515 MPI_Datatype depthType; 5516 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5517 const PetscInt *localPoints, *neighbors; 5518 const PetscSFNode *remotePoints; 5519 PetscInt *localPointsNew; 5520 PetscSFNode *remotePointsNew; 5521 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5522 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5523 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5524 PetscErrorCode ierr; 5525 5526 PetscFunctionBegin; 5527 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5528 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5529 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5530 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5531 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5532 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5533 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5534 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5535 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5536 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5537 /* Caculate size of new SF */ 5538 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5539 if (numRoots < 0) PetscFunctionReturn(0); 5540 for (l = 0; l < numLeaves; ++l) { 5541 const PetscInt p = localPoints[l]; 5542 5543 switch (refiner) { 5544 case 1: 5545 /* Simplicial 2D */ 5546 if ((p >= vStart) && (p < vEnd)) { 5547 /* Old vertices stay the same */ 5548 ++numLeavesNew; 5549 } else if ((p >= fStart) && (p < fEnd)) { 5550 /* Old faces add new faces and vertex */ 5551 numLeavesNew += 2 + 1; 5552 } else if ((p >= cStart) && (p < cEnd)) { 5553 /* Old cells add new cells and interior faces */ 5554 numLeavesNew += 4 + 3; 5555 } 5556 break; 5557 case 3: 5558 /* Hybrid Simplicial 2D */ 5559 if ((p >= vStart) && (p < vEnd)) { 5560 /* Interior vertices stay the same */ 5561 ++numLeavesNew; 5562 } else if ((p >= fStart) && (p < fMax)) { 5563 /* Interior faces add new faces and vertex */ 5564 numLeavesNew += 2 + 1; 5565 } else if ((p >= fMax) && (p < fEnd)) { 5566 /* Hybrid faces stay the same */ 5567 ++numLeavesNew; 5568 } else if ((p >= cStart) && (p < cMax)) { 5569 /* Interior cells add new cells and interior faces */ 5570 numLeavesNew += 4 + 3; 5571 } else if ((p >= cMax) && (p < cEnd)) { 5572 /* Hybrid cells add new cells and hybrid face */ 5573 numLeavesNew += 2 + 1; 5574 } 5575 break; 5576 case 2: 5577 /* Hex 2D */ 5578 if ((p >= vStart) && (p < vEnd)) { 5579 /* Old vertices stay the same */ 5580 ++numLeavesNew; 5581 } else if ((p >= fStart) && (p < fEnd)) { 5582 /* Old faces add new faces and vertex */ 5583 numLeavesNew += 2 + 1; 5584 } else if ((p >= cStart) && (p < cEnd)) { 5585 /* Old cells add new cells, interior faces, and vertex */ 5586 numLeavesNew += 4 + 4 + 1; 5587 } 5588 break; 5589 case 4: 5590 /* Hybrid Hex 2D */ 5591 if ((p >= vStart) && (p < vEnd)) { 5592 /* Interior vertices stay the same */ 5593 ++numLeavesNew; 5594 } else if ((p >= fStart) && (p < fMax)) { 5595 /* Interior faces add new faces and vertex */ 5596 numLeavesNew += 2 + 1; 5597 } else if ((p >= fMax) && (p < fEnd)) { 5598 /* Hybrid faces stay the same */ 5599 ++numLeavesNew; 5600 } else if ((p >= cStart) && (p < cMax)) { 5601 /* Interior cells add new cells, interior faces, and vertex */ 5602 numLeavesNew += 4 + 4 + 1; 5603 } else if ((p >= cMax) && (p < cEnd)) { 5604 /* Hybrid cells add new cells and hybrid face */ 5605 numLeavesNew += 2 + 1; 5606 } 5607 break; 5608 case 5: 5609 /* Simplicial 3D */ 5610 if ((p >= vStart) && (p < vEnd)) { 5611 /* Old vertices stay the same */ 5612 ++numLeavesNew; 5613 } else if ((p >= eStart) && (p < eEnd)) { 5614 /* Old edges add new edges and vertex */ 5615 numLeavesNew += 2 + 1; 5616 } else if ((p >= fStart) && (p < fEnd)) { 5617 /* Old faces add new faces and face edges */ 5618 numLeavesNew += 4 + 3; 5619 } else if ((p >= cStart) && (p < cEnd)) { 5620 /* Old cells add new cells and interior faces and edges */ 5621 numLeavesNew += 8 + 8 + 1; 5622 } 5623 break; 5624 case 7: 5625 /* Hybrid Simplicial 3D */ 5626 if ((p >= vStart) && (p < vEnd)) { 5627 /* Interior vertices stay the same */ 5628 ++numLeavesNew; 5629 } else if ((p >= eStart) && (p < eMax)) { 5630 /* Interior edges add new edges and vertex */ 5631 numLeavesNew += 2 + 1; 5632 } else if ((p >= eMax) && (p < eEnd)) { 5633 /* Hybrid edges stay the same */ 5634 ++numLeavesNew; 5635 } else if ((p >= fStart) && (p < fMax)) { 5636 /* Interior faces add new faces and edges */ 5637 numLeavesNew += 4 + 3; 5638 } else if ((p >= fMax) && (p < fEnd)) { 5639 /* Hybrid faces add new faces and edges */ 5640 numLeavesNew += 2 + 1; 5641 } else if ((p >= cStart) && (p < cMax)) { 5642 /* Interior cells add new cells, faces, and edges */ 5643 numLeavesNew += 8 + 8 + 1; 5644 } else if ((p >= cMax) && (p < cEnd)) { 5645 /* Hybrid cells add new cells and faces */ 5646 numLeavesNew += 4 + 3; 5647 } 5648 break; 5649 case 6: 5650 /* Hex 3D */ 5651 if ((p >= vStart) && (p < vEnd)) { 5652 /* Old vertices stay the same */ 5653 ++numLeavesNew; 5654 } else if ((p >= eStart) && (p < eEnd)) { 5655 /* Old edges add new edges, and vertex */ 5656 numLeavesNew += 2 + 1; 5657 } else if ((p >= fStart) && (p < fEnd)) { 5658 /* Old faces add new faces, edges, and vertex */ 5659 numLeavesNew += 4 + 4 + 1; 5660 } else if ((p >= cStart) && (p < cEnd)) { 5661 /* Old cells add new cells, faces, edges, and vertex */ 5662 numLeavesNew += 8 + 12 + 6 + 1; 5663 } 5664 break; 5665 case 8: 5666 /* Hybrid Hex 3D */ 5667 if ((p >= vStart) && (p < vEnd)) { 5668 /* Old vertices stay the same */ 5669 ++numLeavesNew; 5670 } else if ((p >= eStart) && (p < eMax)) { 5671 /* Interior edges add new edges, and vertex */ 5672 numLeavesNew += 2 + 1; 5673 } else if ((p >= eMax) && (p < eEnd)) { 5674 /* Hybrid edges stay the same */ 5675 ++numLeavesNew; 5676 } else if ((p >= fStart) && (p < fMax)) { 5677 /* Interior faces add new faces, edges, and vertex */ 5678 numLeavesNew += 4 + 4 + 1; 5679 } else if ((p >= fMax) && (p < fEnd)) { 5680 /* Hybrid faces add new faces and edges */ 5681 numLeavesNew += 2 + 1; 5682 } else if ((p >= cStart) && (p < cMax)) { 5683 /* Interior cells add new cells, faces, edges, and vertex */ 5684 numLeavesNew += 8 + 12 + 6 + 1; 5685 } else if ((p >= cStart) && (p < cEnd)) { 5686 /* Hybrid cells add new cells, faces, and edges */ 5687 numLeavesNew += 4 + 4 + 1; 5688 } 5689 break; 5690 default: 5691 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5692 } 5693 } 5694 /* Communicate depthSizes for each remote rank */ 5695 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5696 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5697 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5698 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5699 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5700 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5701 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5702 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5703 for (n = 0; n < numNeighbors; ++n) { 5704 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5705 } 5706 depthSizeOld[depth] = cMax; 5707 depthSizeOld[0] = vMax; 5708 depthSizeOld[depth-1] = fMax; 5709 depthSizeOld[1] = eMax; 5710 5711 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5712 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5713 5714 depthSizeOld[depth] = cEnd - cStart; 5715 depthSizeOld[0] = vEnd - vStart; 5716 depthSizeOld[depth-1] = fEnd - fStart; 5717 depthSizeOld[1] = eEnd - eStart; 5718 5719 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5720 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5721 for (n = 0; n < numNeighbors; ++n) { 5722 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5723 } 5724 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5725 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5726 /* Calculate new point SF */ 5727 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5728 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5729 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5730 for (l = 0, m = 0; l < numLeaves; ++l) { 5731 PetscInt p = localPoints[l]; 5732 PetscInt rp = remotePoints[l].index, n; 5733 PetscMPIInt rrank = remotePoints[l].rank; 5734 5735 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5736 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5737 switch (refiner) { 5738 case 1: 5739 /* Simplicial 2D */ 5740 if ((p >= vStart) && (p < vEnd)) { 5741 /* Old vertices stay the same */ 5742 localPointsNew[m] = vStartNew + (p - vStart); 5743 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5744 remotePointsNew[m].rank = rrank; 5745 ++m; 5746 } else if ((p >= fStart) && (p < fEnd)) { 5747 /* Old faces add new faces and vertex */ 5748 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5749 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5750 remotePointsNew[m].rank = rrank; 5751 ++m; 5752 for (r = 0; r < 2; ++r, ++m) { 5753 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5754 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5755 remotePointsNew[m].rank = rrank; 5756 } 5757 } else if ((p >= cStart) && (p < cEnd)) { 5758 /* Old cells add new cells and interior faces */ 5759 for (r = 0; r < 4; ++r, ++m) { 5760 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5761 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5762 remotePointsNew[m].rank = rrank; 5763 } 5764 for (r = 0; r < 3; ++r, ++m) { 5765 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5766 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 5767 remotePointsNew[m].rank = rrank; 5768 } 5769 } 5770 break; 5771 case 2: 5772 /* Hex 2D */ 5773 if ((p >= vStart) && (p < vEnd)) { 5774 /* Old vertices stay the same */ 5775 localPointsNew[m] = vStartNew + (p - vStart); 5776 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5777 remotePointsNew[m].rank = rrank; 5778 ++m; 5779 } else if ((p >= fStart) && (p < fEnd)) { 5780 /* Old faces add new faces and vertex */ 5781 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5782 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5783 remotePointsNew[m].rank = rrank; 5784 ++m; 5785 for (r = 0; r < 2; ++r, ++m) { 5786 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5787 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5788 remotePointsNew[m].rank = rrank; 5789 } 5790 } else if ((p >= cStart) && (p < cEnd)) { 5791 /* Old cells add new cells, interior faces, and vertex */ 5792 for (r = 0; r < 4; ++r, ++m) { 5793 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5794 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5795 remotePointsNew[m].rank = rrank; 5796 } 5797 for (r = 0; r < 4; ++r, ++m) { 5798 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 5799 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 5800 remotePointsNew[m].rank = rrank; 5801 } 5802 for (r = 0; r < 1; ++r, ++m) { 5803 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart) + r; 5804 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 5805 remotePointsNew[m].rank = rrank; 5806 } 5807 } 5808 break; 5809 case 3: 5810 /* Hybrid simplicial 2D */ 5811 if ((p >= vStart) && (p < vEnd)) { 5812 /* Old vertices stay the same */ 5813 localPointsNew[m] = vStartNew + (p - vStart); 5814 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5815 remotePointsNew[m].rank = rrank; 5816 ++m; 5817 } else if ((p >= fStart) && (p < fMax)) { 5818 /* Old interior faces add new faces and vertex */ 5819 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5820 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5821 remotePointsNew[m].rank = rrank; 5822 ++m; 5823 for (r = 0; r < 2; ++r, ++m) { 5824 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5825 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5826 remotePointsNew[m].rank = rrank; 5827 } 5828 } else if ((p >= fMax) && (p < fEnd)) { 5829 /* Old hybrid faces stay the same */ 5830 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5831 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5832 remotePointsNew[m].rank = rrank; 5833 ++m; 5834 } else if ((p >= cStart) && (p < cMax)) { 5835 /* Old interior cells add new cells and interior faces */ 5836 for (r = 0; r < 4; ++r, ++m) { 5837 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5838 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5839 remotePointsNew[m].rank = rrank; 5840 } 5841 for (r = 0; r < 3; ++r, ++m) { 5842 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5843 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5844 remotePointsNew[m].rank = rrank; 5845 } 5846 } else if ((p >= cStart) && (p < cMax)) { 5847 /* Old hybrid cells add new cells and hybrid face */ 5848 for (r = 0; r < 2; ++r, ++m) { 5849 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5850 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5851 remotePointsNew[m].rank = rrank; 5852 } 5853 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5854 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]); 5855 remotePointsNew[m].rank = rrank; 5856 ++m; 5857 } 5858 break; 5859 case 4: 5860 /* Hybrid Hex 2D */ 5861 if ((p >= vStart) && (p < vEnd)) { 5862 /* Old vertices stay the same */ 5863 localPointsNew[m] = vStartNew + (p - vStart); 5864 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5865 remotePointsNew[m].rank = rrank; 5866 ++m; 5867 } else if ((p >= fStart) && (p < fMax)) { 5868 /* Old interior faces add new faces and vertex */ 5869 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5870 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5871 remotePointsNew[m].rank = rrank; 5872 ++m; 5873 for (r = 0; r < 2; ++r, ++m) { 5874 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5875 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5876 remotePointsNew[m].rank = rrank; 5877 } 5878 } else if ((p >= fMax) && (p < fEnd)) { 5879 /* Old hybrid faces stay the same */ 5880 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5881 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5882 remotePointsNew[m].rank = rrank; 5883 ++m; 5884 } else if ((p >= cStart) && (p < cMax)) { 5885 /* Old interior cells add new cells, interior faces, and vertex */ 5886 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 5887 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 5888 remotePointsNew[m].rank = rrank; 5889 ++m; 5890 for (r = 0; r < 4; ++r, ++m) { 5891 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5892 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5893 remotePointsNew[m].rank = rrank; 5894 } 5895 for (r = 0; r < 4; ++r, ++m) { 5896 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5897 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5898 remotePointsNew[m].rank = rrank; 5899 } 5900 } else if ((p >= cStart) && (p < cMax)) { 5901 /* Old hybrid cells add new cells and hybrid face */ 5902 for (r = 0; r < 2; ++r, ++m) { 5903 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5904 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5905 remotePointsNew[m].rank = rrank; 5906 } 5907 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5908 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]); 5909 remotePointsNew[m].rank = rrank; 5910 ++m; 5911 } 5912 break; 5913 case 5: 5914 /* Simplicial 3D */ 5915 if ((p >= vStart) && (p < vEnd)) { 5916 /* Old vertices stay the same */ 5917 localPointsNew[m] = vStartNew + (p - vStart); 5918 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5919 remotePointsNew[m].rank = rrank; 5920 ++m; 5921 } else if ((p >= eStart) && (p < eEnd)) { 5922 /* Old edges add new edges and vertex */ 5923 for (r = 0; r < 2; ++r, ++m) { 5924 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5925 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5926 remotePointsNew[m].rank = rrank; 5927 } 5928 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5929 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5930 remotePointsNew[m].rank = rrank; 5931 ++m; 5932 } else if ((p >= fStart) && (p < fEnd)) { 5933 /* Old faces add new faces and face edges */ 5934 for (r = 0; r < 4; ++r, ++m) { 5935 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5936 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5937 remotePointsNew[m].rank = rrank; 5938 } 5939 for (r = 0; r < 3; ++r, ++m) { 5940 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 5941 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 5942 remotePointsNew[m].rank = rrank; 5943 } 5944 } else if ((p >= cStart) && (p < cEnd)) { 5945 /* Old cells add new cells and interior faces and edges */ 5946 for (r = 0; r < 8; ++r, ++m) { 5947 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5948 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5949 remotePointsNew[m].rank = rrank; 5950 } 5951 for (r = 0; r < 8; ++r, ++m) { 5952 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 5953 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 5954 remotePointsNew[m].rank = rrank; 5955 } 5956 for (r = 0; r < 1; ++r, ++m) { 5957 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 5958 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 5959 remotePointsNew[m].rank = rrank; 5960 } 5961 } 5962 break; 5963 case 7: 5964 /* Hybrid Simplicial 3D */ 5965 if ((p >= vStart) && (p < vEnd)) { 5966 /* Interior vertices stay the same */ 5967 localPointsNew[m] = vStartNew + (p - vStart); 5968 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5969 remotePointsNew[m].rank = rrank; 5970 ++m; 5971 } else if ((p >= eStart) && (p < eMax)) { 5972 /* Interior edges add new edges and vertex */ 5973 for (r = 0; r < 2; ++r, ++m) { 5974 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5975 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5976 remotePointsNew[m].rank = rrank; 5977 } 5978 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5979 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5980 remotePointsNew[m].rank = rrank; 5981 ++m; 5982 } else if ((p >= eMax) && (p < eEnd)) { 5983 /* Hybrid edges stay the same */ 5984 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5985 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]); 5986 remotePointsNew[m].rank = rrank; 5987 ++m; 5988 } else if ((p >= fStart) && (p < fMax)) { 5989 /* Interior faces add new faces and edges */ 5990 for (r = 0; r < 4; ++r, ++m) { 5991 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5992 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5993 remotePointsNew[m].rank = rrank; 5994 } 5995 for (r = 0; r < 3; ++r, ++m) { 5996 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5997 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5998 remotePointsNew[m].rank = rrank; 5999 } 6000 } else if ((p >= fMax) && (p < fEnd)) { 6001 /* Hybrid faces add new faces and edges */ 6002 for (r = 0; r < 2; ++r, ++m) { 6003 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6004 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; 6005 remotePointsNew[m].rank = rrank; 6006 } 6007 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 6008 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]); 6009 remotePointsNew[m].rank = rrank; 6010 ++m; 6011 } else if ((p >= cStart) && (p < cMax)) { 6012 /* Interior cells add new cells, faces, and edges */ 6013 for (r = 0; r < 8; ++r, ++m) { 6014 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6015 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6016 remotePointsNew[m].rank = rrank; 6017 } 6018 for (r = 0; r < 8; ++r, ++m) { 6019 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6020 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 6021 remotePointsNew[m].rank = rrank; 6022 } 6023 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 6024 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; 6025 remotePointsNew[m].rank = rrank; 6026 ++m; 6027 } else if ((p >= cMax) && (p < cEnd)) { 6028 /* Hybrid cells add new cells and faces */ 6029 for (r = 0; r < 4; ++r, ++m) { 6030 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6031 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6032 remotePointsNew[m].rank = rrank; 6033 } 6034 for (r = 0; r < 3; ++r, ++m) { 6035 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6036 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; 6037 remotePointsNew[m].rank = rrank; 6038 } 6039 } 6040 break; 6041 case 6: 6042 /* Hex 3D */ 6043 if ((p >= vStart) && (p < vEnd)) { 6044 /* Old vertices stay the same */ 6045 localPointsNew[m] = vStartNew + (p - vStart); 6046 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6047 remotePointsNew[m].rank = rrank; 6048 ++m; 6049 } else if ((p >= eStart) && (p < eEnd)) { 6050 /* Old edges add new edges and vertex */ 6051 for (r = 0; r < 2; ++r, ++m) { 6052 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6053 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6054 remotePointsNew[m].rank = rrank; 6055 } 6056 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6057 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6058 remotePointsNew[m].rank = rrank; 6059 ++m; 6060 } else if ((p >= fStart) && (p < fEnd)) { 6061 /* Old faces add new faces, edges, and vertex */ 6062 for (r = 0; r < 4; ++r, ++m) { 6063 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6064 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6065 remotePointsNew[m].rank = rrank; 6066 } 6067 for (r = 0; r < 4; ++r, ++m) { 6068 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6069 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 6070 remotePointsNew[m].rank = rrank; 6071 } 6072 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6073 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 6074 remotePointsNew[m].rank = rrank; 6075 ++m; 6076 } else if ((p >= cStart) && (p < cEnd)) { 6077 /* Old cells add new cells, faces, edges, and vertex */ 6078 for (r = 0; r < 8; ++r, ++m) { 6079 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6080 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6081 remotePointsNew[m].rank = rrank; 6082 } 6083 for (r = 0; r < 12; ++r, ++m) { 6084 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6085 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 6086 remotePointsNew[m].rank = rrank; 6087 } 6088 for (r = 0; r < 6; ++r, ++m) { 6089 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6090 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 6091 remotePointsNew[m].rank = rrank; 6092 } 6093 for (r = 0; r < 1; ++r, ++m) { 6094 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 6095 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 6096 remotePointsNew[m].rank = rrank; 6097 } 6098 } 6099 break; 6100 case 8: 6101 /* Hybrid Hex 3D */ 6102 if ((p >= vStart) && (p < vEnd)) { 6103 /* Interior vertices stay the same */ 6104 localPointsNew[m] = vStartNew + (p - vStart); 6105 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6106 remotePointsNew[m].rank = rrank; 6107 ++m; 6108 } else if ((p >= eStart) && (p < eMax)) { 6109 /* Interior edges add new edges and vertex */ 6110 for (r = 0; r < 2; ++r, ++m) { 6111 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6112 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6113 remotePointsNew[m].rank = rrank; 6114 } 6115 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6116 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6117 remotePointsNew[m].rank = rrank; 6118 ++m; 6119 } else if ((p >= eMax) && (p < eEnd)) { 6120 /* Hybrid edges stay the same */ 6121 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6122 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+1]); 6123 remotePointsNew[m].rank = rrank; 6124 ++m; 6125 } else if ((p >= fStart) && (p < fMax)) { 6126 /* Interior faces add new faces, edges, and vertex */ 6127 for (r = 0; r < 4; ++r, ++m) { 6128 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6129 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6130 remotePointsNew[m].rank = rrank; 6131 } 6132 for (r = 0; r < 4; ++r, ++m) { 6133 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6134 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 6135 remotePointsNew[m].rank = rrank; 6136 } 6137 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6138 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 6139 remotePointsNew[m].rank = rrank; 6140 ++m; 6141 } else if ((p >= fMax) && (p < fEnd)) { 6142 /* Hybrid faces add new faces and edges */ 6143 for (r = 0; r < 2; ++r, ++m) { 6144 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6145 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; 6146 remotePointsNew[m].rank = rrank; 6147 } 6148 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax); 6149 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]); 6150 remotePointsNew[m].rank = rrank; 6151 ++m; 6152 } else if ((p >= cStart) && (p < cMax)) { 6153 /* Interior cells add new cells, faces, edges, and vertex */ 6154 for (r = 0; r < 8; ++r, ++m) { 6155 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6156 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6157 remotePointsNew[m].rank = rrank; 6158 } 6159 for (r = 0; r < 12; ++r, ++m) { 6160 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6161 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6162 remotePointsNew[m].rank = rrank; 6163 } 6164 for (r = 0; r < 6; ++r, ++m) { 6165 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6166 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; 6167 remotePointsNew[m].rank = rrank; 6168 } 6169 for (r = 0; r < 1; ++r, ++m) { 6170 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6171 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6172 remotePointsNew[m].rank = rrank; 6173 } 6174 } else if ((p >= cMax) && (p < cEnd)) { 6175 /* Hybrid cells add new cells, faces, and edges */ 6176 for (r = 0; r < 4; ++r, ++m) { 6177 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6178 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6179 remotePointsNew[m].rank = rrank; 6180 } 6181 for (r = 0; r < 4; ++r, ++m) { 6182 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6183 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6184 remotePointsNew[m].rank = rrank; 6185 } 6186 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6187 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]); 6188 remotePointsNew[m].rank = rrank; 6189 ++m; 6190 } 6191 break; 6192 default: 6193 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6194 } 6195 } 6196 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6197 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6198 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6199 { 6200 PetscSFNode *rp, *rtmp; 6201 PetscInt *lp, *idx, *ltmp, i; 6202 6203 /* SF needs sorted leaves to correct calculate Gather */ 6204 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 6205 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 6206 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 6207 for (i = 0; i < numLeavesNew; ++i) idx[i] = i; 6208 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 6209 for (i = 0; i < numLeavesNew; ++i) { 6210 lp[i] = localPointsNew[idx[i]]; 6211 rp[i] = remotePointsNew[idx[i]]; 6212 } 6213 ltmp = localPointsNew; 6214 localPointsNew = lp; 6215 rtmp = remotePointsNew; 6216 remotePointsNew = rp; 6217 ierr = PetscFree(idx);CHKERRQ(ierr); 6218 ierr = PetscFree(ltmp);CHKERRQ(ierr); 6219 ierr = PetscFree(rtmp);CHKERRQ(ierr); 6220 } 6221 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6222 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6223 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6224 PetscFunctionReturn(0); 6225 } 6226 6227 #undef __FUNCT__ 6228 #define __FUNCT__ "CellRefinerCreateLabels" 6229 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6230 { 6231 PetscInt numLabels, l; 6232 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6233 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6234 PetscErrorCode ierr; 6235 6236 PetscFunctionBegin; 6237 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6238 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6239 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6240 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6241 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6242 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6243 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6244 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6245 switch (refiner) { 6246 case 0: break; 6247 case 7: 6248 case 8: 6249 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6250 case 3: 6251 case 4: 6252 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6253 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6254 } 6255 for (l = 0; l < numLabels; ++l) { 6256 DMLabel label, labelNew; 6257 const char *lname; 6258 PetscBool isDepth; 6259 IS valueIS; 6260 const PetscInt *values; 6261 PetscInt numValues, val; 6262 6263 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6264 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6265 if (isDepth) continue; 6266 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6267 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6268 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6269 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6270 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6271 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6272 for (val = 0; val < numValues; ++val) { 6273 IS pointIS; 6274 const PetscInt *points; 6275 PetscInt numPoints, n; 6276 6277 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6278 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6279 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6280 for (n = 0; n < numPoints; ++n) { 6281 const PetscInt p = points[n]; 6282 switch (refiner) { 6283 case 1: 6284 /* Simplicial 2D */ 6285 if ((p >= vStart) && (p < vEnd)) { 6286 /* Old vertices stay the same */ 6287 newp = vStartNew + (p - vStart); 6288 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6289 } else if ((p >= fStart) && (p < fEnd)) { 6290 /* Old faces add new faces and vertex */ 6291 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6292 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6293 for (r = 0; r < 2; ++r) { 6294 newp = fStartNew + (p - fStart)*2 + r; 6295 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6296 } 6297 } else if ((p >= cStart) && (p < cEnd)) { 6298 /* Old cells add new cells and interior faces */ 6299 for (r = 0; r < 4; ++r) { 6300 newp = cStartNew + (p - cStart)*4 + r; 6301 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6302 } 6303 for (r = 0; r < 3; ++r) { 6304 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6305 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6306 } 6307 } 6308 break; 6309 case 2: 6310 /* Hex 2D */ 6311 if ((p >= vStart) && (p < vEnd)) { 6312 /* Old vertices stay the same */ 6313 newp = vStartNew + (p - vStart); 6314 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6315 } else if ((p >= fStart) && (p < fEnd)) { 6316 /* Old faces add new faces and vertex */ 6317 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6318 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6319 for (r = 0; r < 2; ++r) { 6320 newp = fStartNew + (p - fStart)*2 + r; 6321 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6322 } 6323 } else if ((p >= cStart) && (p < cEnd)) { 6324 /* Old cells add new cells and interior faces and vertex */ 6325 for (r = 0; r < 4; ++r) { 6326 newp = cStartNew + (p - cStart)*4 + r; 6327 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6328 } 6329 for (r = 0; r < 4; ++r) { 6330 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6331 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6332 } 6333 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6334 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6335 } 6336 break; 6337 case 3: 6338 /* Hybrid simplicial 2D */ 6339 if ((p >= vStart) && (p < vEnd)) { 6340 /* Old vertices stay the same */ 6341 newp = vStartNew + (p - vStart); 6342 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6343 } else if ((p >= fStart) && (p < fMax)) { 6344 /* Old interior faces add new faces and vertex */ 6345 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6346 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6347 for (r = 0; r < 2; ++r) { 6348 newp = fStartNew + (p - fStart)*2 + r; 6349 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6350 } 6351 } else if ((p >= fMax) && (p < fEnd)) { 6352 /* Old hybrid faces stay the same */ 6353 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6354 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6355 } else if ((p >= cStart) && (p < cMax)) { 6356 /* Old interior cells add new cells and interior faces */ 6357 for (r = 0; r < 4; ++r) { 6358 newp = cStartNew + (p - cStart)*4 + r; 6359 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6360 } 6361 for (r = 0; r < 3; ++r) { 6362 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6363 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6364 } 6365 } else if ((p >= cMax) && (p < cEnd)) { 6366 /* Old hybrid cells add new cells and hybrid face */ 6367 for (r = 0; r < 2; ++r) { 6368 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6369 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6370 } 6371 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6372 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6373 } 6374 break; 6375 case 4: 6376 /* Hybrid Hex 2D */ 6377 if ((p >= vStart) && (p < vEnd)) { 6378 /* Old vertices stay the same */ 6379 newp = vStartNew + (p - vStart); 6380 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6381 } else if ((p >= fStart) && (p < fMax)) { 6382 /* Old interior faces add new faces and vertex */ 6383 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6384 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6385 for (r = 0; r < 2; ++r) { 6386 newp = fStartNew + (p - fStart)*2 + r; 6387 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6388 } 6389 } else if ((p >= fMax) && (p < fEnd)) { 6390 /* Old hybrid faces stay the same */ 6391 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6392 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6393 } else if ((p >= cStart) && (p < cMax)) { 6394 /* Old interior cells add new cells, interior faces, and vertex */ 6395 for (r = 0; r < 4; ++r) { 6396 newp = cStartNew + (p - cStart)*4 + r; 6397 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6398 } 6399 for (r = 0; r < 4; ++r) { 6400 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6401 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6402 } 6403 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6404 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6405 } else if ((p >= cMax) && (p < cEnd)) { 6406 /* Old hybrid cells add new cells and hybrid face */ 6407 for (r = 0; r < 2; ++r) { 6408 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6409 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6410 } 6411 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6412 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6413 } 6414 break; 6415 case 5: 6416 /* Simplicial 3D */ 6417 if ((p >= vStart) && (p < vEnd)) { 6418 /* Old vertices stay the same */ 6419 newp = vStartNew + (p - vStart); 6420 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6421 } else if ((p >= eStart) && (p < eEnd)) { 6422 /* Old edges add new edges and vertex */ 6423 for (r = 0; r < 2; ++r) { 6424 newp = eStartNew + (p - eStart)*2 + r; 6425 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6426 } 6427 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6428 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6429 } else if ((p >= fStart) && (p < fEnd)) { 6430 /* Old faces add new faces and edges */ 6431 for (r = 0; r < 4; ++r) { 6432 newp = fStartNew + (p - fStart)*4 + r; 6433 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6434 } 6435 for (r = 0; r < 3; ++r) { 6436 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6437 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6438 } 6439 } else if ((p >= cStart) && (p < cEnd)) { 6440 /* Old cells add new cells and interior faces and edges */ 6441 for (r = 0; r < 8; ++r) { 6442 newp = cStartNew + (p - cStart)*8 + r; 6443 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6444 } 6445 for (r = 0; r < 8; ++r) { 6446 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6447 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6448 } 6449 for (r = 0; r < 1; ++r) { 6450 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6451 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6452 } 6453 } 6454 break; 6455 case 7: 6456 /* Hybrid Simplicial 3D */ 6457 if ((p >= vStart) && (p < vEnd)) { 6458 /* Interior vertices stay the same */ 6459 newp = vStartNew + (p - vStart); 6460 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6461 } else if ((p >= eStart) && (p < eMax)) { 6462 /* Interior edges add new edges and vertex */ 6463 for (r = 0; r < 2; ++r) { 6464 newp = eStartNew + (p - eStart)*2 + r; 6465 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6466 } 6467 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6468 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6469 } else if ((p >= eMax) && (p < eEnd)) { 6470 /* Hybrid edges stay the same */ 6471 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6472 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6473 } else if ((p >= fStart) && (p < fMax)) { 6474 /* Interior faces add new faces and edges */ 6475 for (r = 0; r < 4; ++r) { 6476 newp = fStartNew + (p - fStart)*4 + r; 6477 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6478 } 6479 for (r = 0; r < 3; ++r) { 6480 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6481 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6482 } 6483 } else if ((p >= fMax) && (p < fEnd)) { 6484 /* Hybrid faces add new faces and edges */ 6485 for (r = 0; r < 2; ++r) { 6486 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6487 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6488 } 6489 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6490 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6491 } else if ((p >= cStart) && (p < cMax)) { 6492 /* Interior cells add new cells, faces, and edges */ 6493 for (r = 0; r < 8; ++r) { 6494 newp = cStartNew + (p - cStart)*8 + r; 6495 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6496 } 6497 for (r = 0; r < 8; ++r) { 6498 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6499 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6500 } 6501 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6502 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6503 } else if ((p >= cMax) && (p < cEnd)) { 6504 /* Hybrid cells add new cells and faces */ 6505 for (r = 0; r < 4; ++r) { 6506 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6507 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6508 } 6509 for (r = 0; r < 3; ++r) { 6510 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6511 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6512 } 6513 } 6514 break; 6515 case 6: 6516 /* Hex 3D */ 6517 if ((p >= vStart) && (p < vEnd)) { 6518 /* Old vertices stay the same */ 6519 newp = vStartNew + (p - vStart); 6520 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6521 } else if ((p >= eStart) && (p < eEnd)) { 6522 /* Old edges add new edges and vertex */ 6523 for (r = 0; r < 2; ++r) { 6524 newp = eStartNew + (p - eStart)*2 + r; 6525 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6526 } 6527 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6528 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6529 } else if ((p >= fStart) && (p < fEnd)) { 6530 /* Old faces add new faces, edges, and vertex */ 6531 for (r = 0; r < 4; ++r) { 6532 newp = fStartNew + (p - fStart)*4 + r; 6533 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6534 } 6535 for (r = 0; r < 4; ++r) { 6536 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6537 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6538 } 6539 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6540 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6541 } else if ((p >= cStart) && (p < cEnd)) { 6542 /* Old cells add new cells, faces, edges, and vertex */ 6543 for (r = 0; r < 8; ++r) { 6544 newp = cStartNew + (p - cStart)*8 + r; 6545 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6546 } 6547 for (r = 0; r < 12; ++r) { 6548 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6549 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6550 } 6551 for (r = 0; r < 6; ++r) { 6552 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6553 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6554 } 6555 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6556 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6557 } 6558 break; 6559 case 8: 6560 /* Hybrid Hex 3D */ 6561 if ((p >= vStart) && (p < vEnd)) { 6562 /* Interior vertices stay the same */ 6563 newp = vStartNew + (p - vStart); 6564 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6565 } else if ((p >= eStart) && (p < eMax)) { 6566 /* Interior edges add new edges and vertex */ 6567 for (r = 0; r < 2; ++r) { 6568 newp = eStartNew + (p - eStart)*2 + r; 6569 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6570 } 6571 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6572 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6573 } else if ((p >= eMax) && (p < eEnd)) { 6574 /* Hybrid edges stay the same */ 6575 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6576 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6577 } else if ((p >= fStart) && (p < fMax)) { 6578 /* Interior faces add new faces, edges, and vertex */ 6579 for (r = 0; r < 4; ++r) { 6580 newp = fStartNew + (p - fStart)*4 + r; 6581 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6582 } 6583 for (r = 0; r < 4; ++r) { 6584 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6585 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6586 } 6587 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6588 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6589 } else if ((p >= fMax) && (p < fEnd)) { 6590 /* Hybrid faces add new faces and edges */ 6591 for (r = 0; r < 2; ++r) { 6592 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6593 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6594 } 6595 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6596 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6597 } else if ((p >= cStart) && (p < cMax)) { 6598 /* Interior cells add new cells, faces, edges, and vertex */ 6599 for (r = 0; r < 8; ++r) { 6600 newp = cStartNew + (p - cStart)*8 + r; 6601 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6602 } 6603 for (r = 0; r < 12; ++r) { 6604 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6605 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6606 } 6607 for (r = 0; r < 6; ++r) { 6608 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6609 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6610 } 6611 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6612 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6613 } else if ((p >= cMax) && (p < cEnd)) { 6614 /* Hybrid cells add new cells, faces, and edges */ 6615 for (r = 0; r < 4; ++r) { 6616 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6617 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6618 } 6619 for (r = 0; r < 4; ++r) { 6620 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6621 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6622 } 6623 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6624 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6625 } 6626 break; 6627 default: 6628 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6629 } 6630 } 6631 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6632 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6633 } 6634 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6635 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6636 if (0) { 6637 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6638 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6639 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6640 } 6641 } 6642 PetscFunctionReturn(0); 6643 } 6644 6645 #undef __FUNCT__ 6646 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6647 /* This will only work for interpolated meshes */ 6648 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6649 { 6650 DM rdm; 6651 PetscInt *depthSize; 6652 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6653 PetscErrorCode ierr; 6654 6655 PetscFunctionBegin; 6656 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6657 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6658 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6659 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 6660 /* Calculate number of new points of each depth */ 6661 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6662 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6663 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6664 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6665 /* Step 1: Set chart */ 6666 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6667 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6668 /* Step 2: Set cone/support sizes */ 6669 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6670 /* Step 3: Setup refined DM */ 6671 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6672 /* Step 4: Set cones and supports */ 6673 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6674 /* Step 5: Stratify */ 6675 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6676 /* Step 6: Set coordinates for vertices */ 6677 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6678 /* Step 7: Create pointSF */ 6679 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6680 /* Step 8: Create labels */ 6681 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6682 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6683 6684 *dmRefined = rdm; 6685 PetscFunctionReturn(0); 6686 } 6687 6688 #undef __FUNCT__ 6689 #define __FUNCT__ "DMPlexCreateCoarsePointIS" 6690 /*@ 6691 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 6692 6693 Input Parameter: 6694 . dm - The coarse DM 6695 6696 Output Parameter: 6697 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 6698 6699 Level: developer 6700 6701 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 6702 @*/ 6703 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 6704 { 6705 CellRefiner cellRefiner; 6706 PetscInt *depthSize, *fpoints; 6707 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6708 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 6709 PetscErrorCode ierr; 6710 6711 PetscFunctionBegin; 6712 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6713 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6714 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6715 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 6716 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6717 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6718 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6719 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 6720 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 6721 switch (cellRefiner) { 6722 case 1: /* Simplicial 2D */ 6723 case 3: /* Hybrid simplicial 2D */ 6724 case 2: /* Hex 2D */ 6725 case 4: /* Hybrid Hex 2D */ 6726 case 5: /* Simplicial 3D */ 6727 case 7: /* Hybrid Simplicial 3D */ 6728 case 6: /* Hex 3D */ 6729 case 8: /* Hybrid Hex 3D */ 6730 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 6731 break; 6732 default: 6733 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 6734 } 6735 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 6736 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6737 PetscFunctionReturn(0); 6738 } 6739 6740 #undef __FUNCT__ 6741 #define __FUNCT__ "DMPlexSetRefinementUniform" 6742 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6743 { 6744 DM_Plex *mesh = (DM_Plex*) dm->data; 6745 6746 PetscFunctionBegin; 6747 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6748 mesh->refinementUniform = refinementUniform; 6749 PetscFunctionReturn(0); 6750 } 6751 6752 #undef __FUNCT__ 6753 #define __FUNCT__ "DMPlexGetRefinementUniform" 6754 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6755 { 6756 DM_Plex *mesh = (DM_Plex*) dm->data; 6757 6758 PetscFunctionBegin; 6759 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6760 PetscValidPointer(refinementUniform, 2); 6761 *refinementUniform = mesh->refinementUniform; 6762 PetscFunctionReturn(0); 6763 } 6764 6765 #undef __FUNCT__ 6766 #define __FUNCT__ "DMPlexSetRefinementLimit" 6767 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6768 { 6769 DM_Plex *mesh = (DM_Plex*) dm->data; 6770 6771 PetscFunctionBegin; 6772 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6773 mesh->refinementLimit = refinementLimit; 6774 PetscFunctionReturn(0); 6775 } 6776 6777 #undef __FUNCT__ 6778 #define __FUNCT__ "DMPlexGetRefinementLimit" 6779 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6780 { 6781 DM_Plex *mesh = (DM_Plex*) dm->data; 6782 6783 PetscFunctionBegin; 6784 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6785 PetscValidPointer(refinementLimit, 2); 6786 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6787 *refinementLimit = mesh->refinementLimit; 6788 PetscFunctionReturn(0); 6789 } 6790 6791 #undef __FUNCT__ 6792 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6793 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6794 { 6795 PetscInt dim, cStart, cEnd, coneSize, cMax; 6796 PetscErrorCode ierr; 6797 6798 PetscFunctionBegin; 6799 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6800 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6801 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 6802 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6803 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6804 switch (dim) { 6805 case 2: 6806 switch (coneSize) { 6807 case 3: 6808 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 6809 else *cellRefiner = 1; /* Triangular */ 6810 break; 6811 case 4: 6812 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 6813 else *cellRefiner = 2; /* Quadrilateral */ 6814 break; 6815 default: 6816 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6817 } 6818 break; 6819 case 3: 6820 switch (coneSize) { 6821 case 4: 6822 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 6823 else *cellRefiner = 5; /* Tetrahedral */ 6824 break; 6825 case 6: 6826 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 6827 else *cellRefiner = 6; /* hexahedral */ 6828 break; 6829 default: 6830 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6831 } 6832 break; 6833 default: 6834 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6835 } 6836 PetscFunctionReturn(0); 6837 } 6838