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 spaceDim, 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 = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5347 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5348 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5349 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5350 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5351 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5352 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5353 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5354 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5355 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 5356 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5357 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5358 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);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 spaceDim coordinates */ 5364 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5365 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 5366 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);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 < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5400 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5401 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5402 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5403 } 5404 case 2: /* Hex 2D */ 5405 case 4: /* Hybrid Hex 2D */ 5406 /* Cell vertices have the average of corner coordinates */ 5407 for (c = cStart; c < cMax; ++c) { 5408 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (spaceDim > 2 ? (fMax - fStart) : 0); 5409 PetscInt *cone = NULL; 5410 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5411 5412 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5413 for (p = 0; p < closureSize*2; p += 2) { 5414 const PetscInt point = cone[p]; 5415 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5416 } 5417 for (v = 0; v < coneSize; ++v) { 5418 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5419 } 5420 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5421 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5422 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5423 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5424 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5425 } 5426 case 1: /* Simplicial 2D */ 5427 case 3: /* Hybrid Simplicial 2D */ 5428 case 5: /* Simplicial 3D */ 5429 case 7: /* Hybrid Simplicial 3D */ 5430 /* Edge vertices have the average of endpoint coordinates */ 5431 for (e = eStart; e < eMax; ++e) { 5432 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5433 const PetscInt *cone; 5434 PetscInt coneSize, offA, offB, offnew, d; 5435 5436 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5437 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5438 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5439 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5440 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5441 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5442 ierr = DMPlexLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 5443 for (d = 0; d < spaceDim; ++d) { 5444 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 5445 } 5446 } 5447 /* Old vertices have the same coordinates */ 5448 for (v = vStart; v < vEnd; ++v) { 5449 const PetscInt newv = vStartNew + (v - vStart); 5450 PetscInt off, offnew, d; 5451 5452 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5453 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5454 for (d = 0; d < spaceDim; ++d) { 5455 coordsNew[offnew+d] = coords[off+d]; 5456 } 5457 } 5458 break; 5459 default: 5460 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5461 } 5462 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5463 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5464 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5465 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5466 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5467 if (dm->maxCell) { 5468 const PetscReal *maxCell, *L; 5469 ierr = DMGetPeriodicity(dm, &maxCell, &L);CHKERRQ(ierr); 5470 ierr = DMSetPeriodicity(rdm, maxCell, L);CHKERRQ(ierr); 5471 } 5472 PetscFunctionReturn(0); 5473 } 5474 5475 #undef __FUNCT__ 5476 #define __FUNCT__ "DMPlexCreateProcessSF" 5477 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5478 { 5479 PetscInt numRoots, numLeaves, l; 5480 const PetscInt *localPoints; 5481 const PetscSFNode *remotePoints; 5482 PetscInt *localPointsNew; 5483 PetscSFNode *remotePointsNew; 5484 PetscInt *ranks, *ranksNew; 5485 PetscErrorCode ierr; 5486 5487 PetscFunctionBegin; 5488 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5489 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5490 for (l = 0; l < numLeaves; ++l) { 5491 ranks[l] = remotePoints[l].rank; 5492 } 5493 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5494 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5495 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5496 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5497 for (l = 0; l < numLeaves; ++l) { 5498 ranksNew[l] = ranks[l]; 5499 localPointsNew[l] = l; 5500 remotePointsNew[l].index = 0; 5501 remotePointsNew[l].rank = ranksNew[l]; 5502 } 5503 ierr = PetscFree(ranks);CHKERRQ(ierr); 5504 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 5505 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5506 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5507 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5508 PetscFunctionReturn(0); 5509 } 5510 5511 #undef __FUNCT__ 5512 #define __FUNCT__ "CellRefinerCreateSF" 5513 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5514 { 5515 PetscSF sf, sfNew, sfProcess; 5516 IS processRanks; 5517 MPI_Datatype depthType; 5518 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5519 const PetscInt *localPoints, *neighbors; 5520 const PetscSFNode *remotePoints; 5521 PetscInt *localPointsNew; 5522 PetscSFNode *remotePointsNew; 5523 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5524 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5525 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5526 PetscErrorCode ierr; 5527 5528 PetscFunctionBegin; 5529 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5530 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5531 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5532 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5533 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5534 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5535 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5536 cMax = cMax < 0 ? cEnd : cMax; 5537 fMax = fMax < 0 ? fEnd : fMax; 5538 eMax = eMax < 0 ? eEnd : eMax; 5539 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5540 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5541 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5542 /* Calculate size of new SF */ 5543 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5544 if (numRoots < 0) PetscFunctionReturn(0); 5545 for (l = 0; l < numLeaves; ++l) { 5546 const PetscInt p = localPoints[l]; 5547 5548 switch (refiner) { 5549 case 1: 5550 case 3: 5551 /* Hybrid Simplicial 2D */ 5552 if ((p >= vStart) && (p < vEnd)) { 5553 /* Interior vertices stay the same */ 5554 ++numLeavesNew; 5555 } else if ((p >= fStart) && (p < fMax)) { 5556 /* Interior faces add new faces and vertex */ 5557 numLeavesNew += 2 + 1; 5558 } else if ((p >= fMax) && (p < fEnd)) { 5559 /* Hybrid faces stay the same */ 5560 ++numLeavesNew; 5561 } else if ((p >= cStart) && (p < cMax)) { 5562 /* Interior cells add new cells and interior faces */ 5563 numLeavesNew += 4 + 3; 5564 } else if ((p >= cMax) && (p < cEnd)) { 5565 /* Hybrid cells add new cells and hybrid face */ 5566 numLeavesNew += 2 + 1; 5567 } 5568 break; 5569 case 2: 5570 case 4: 5571 /* Hybrid Hex 2D */ 5572 if ((p >= vStart) && (p < vEnd)) { 5573 /* Interior vertices stay the same */ 5574 ++numLeavesNew; 5575 } else if ((p >= fStart) && (p < fMax)) { 5576 /* Interior faces add new faces and vertex */ 5577 numLeavesNew += 2 + 1; 5578 } else if ((p >= fMax) && (p < fEnd)) { 5579 /* Hybrid faces stay the same */ 5580 ++numLeavesNew; 5581 } else if ((p >= cStart) && (p < cMax)) { 5582 /* Interior cells add new cells, interior faces, and vertex */ 5583 numLeavesNew += 4 + 4 + 1; 5584 } else if ((p >= cMax) && (p < cEnd)) { 5585 /* Hybrid cells add new cells and hybrid face */ 5586 numLeavesNew += 2 + 1; 5587 } 5588 break; 5589 case 5: 5590 case 7: 5591 /* Hybrid Simplicial 3D */ 5592 if ((p >= vStart) && (p < vEnd)) { 5593 /* Interior vertices stay the same */ 5594 ++numLeavesNew; 5595 } else if ((p >= eStart) && (p < eMax)) { 5596 /* Interior edges add new edges and vertex */ 5597 numLeavesNew += 2 + 1; 5598 } else if ((p >= eMax) && (p < eEnd)) { 5599 /* Hybrid edges stay the same */ 5600 ++numLeavesNew; 5601 } else if ((p >= fStart) && (p < fMax)) { 5602 /* Interior faces add new faces and edges */ 5603 numLeavesNew += 4 + 3; 5604 } else if ((p >= fMax) && (p < fEnd)) { 5605 /* Hybrid faces add new faces and edges */ 5606 numLeavesNew += 2 + 1; 5607 } else if ((p >= cStart) && (p < cMax)) { 5608 /* Interior cells add new cells, faces, and edges */ 5609 numLeavesNew += 8 + 8 + 1; 5610 } else if ((p >= cMax) && (p < cEnd)) { 5611 /* Hybrid cells add new cells and faces */ 5612 numLeavesNew += 4 + 3; 5613 } 5614 break; 5615 case 6: 5616 case 8: 5617 /* Hybrid Hex 3D */ 5618 if ((p >= vStart) && (p < vEnd)) { 5619 /* Old vertices stay the same */ 5620 ++numLeavesNew; 5621 } else if ((p >= eStart) && (p < eMax)) { 5622 /* Interior edges add new edges, and vertex */ 5623 numLeavesNew += 2 + 1; 5624 } else if ((p >= eMax) && (p < eEnd)) { 5625 /* Hybrid edges stay the same */ 5626 ++numLeavesNew; 5627 } else if ((p >= fStart) && (p < fMax)) { 5628 /* Interior faces add new faces, edges, and vertex */ 5629 numLeavesNew += 4 + 4 + 1; 5630 } else if ((p >= fMax) && (p < fEnd)) { 5631 /* Hybrid faces add new faces and edges */ 5632 numLeavesNew += 2 + 1; 5633 } else if ((p >= cStart) && (p < cMax)) { 5634 /* Interior cells add new cells, faces, edges, and vertex */ 5635 numLeavesNew += 8 + 12 + 6 + 1; 5636 } else if ((p >= cStart) && (p < cEnd)) { 5637 /* Hybrid cells add new cells, faces, and edges */ 5638 numLeavesNew += 4 + 4 + 1; 5639 } 5640 break; 5641 default: 5642 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5643 } 5644 } 5645 /* Communicate depthSizes for each remote rank */ 5646 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5647 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5648 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5649 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5650 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5651 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5652 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5653 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5654 for (n = 0; n < numNeighbors; ++n) { 5655 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5656 } 5657 depthSizeOld[depth] = cMax; 5658 depthSizeOld[0] = vMax; 5659 depthSizeOld[depth-1] = fMax; 5660 depthSizeOld[1] = eMax; 5661 5662 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5663 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5664 5665 depthSizeOld[depth] = cEnd - cStart; 5666 depthSizeOld[0] = vEnd - vStart; 5667 depthSizeOld[depth-1] = fEnd - fStart; 5668 depthSizeOld[1] = eEnd - eStart; 5669 5670 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5671 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5672 for (n = 0; n < numNeighbors; ++n) { 5673 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5674 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 5675 rdepthMaxOld[n*(depth+1)+depth-1] = rdepthMaxOld[n*(depth+1)+depth-1] < 0 ? rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n]: rdepthMaxOld[n*(depth+1)+depth-1]; 5676 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 5677 } 5678 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5679 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5680 /* Calculate new point SF */ 5681 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5682 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5683 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5684 for (l = 0, m = 0; l < numLeaves; ++l) { 5685 PetscInt p = localPoints[l]; 5686 PetscInt rp = remotePoints[l].index, n; 5687 PetscMPIInt rrank = remotePoints[l].rank; 5688 5689 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5690 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5691 switch (refiner) { 5692 case 1: 5693 case 3: 5694 /* Hybrid simplicial 2D */ 5695 if ((p >= vStart) && (p < vEnd)) { 5696 /* Old vertices stay the same */ 5697 localPointsNew[m] = vStartNew + (p - vStart); 5698 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5699 remotePointsNew[m].rank = rrank; 5700 ++m; 5701 } else if ((p >= fStart) && (p < fMax)) { 5702 /* Old interior faces add new faces and vertex */ 5703 for (r = 0; r < 2; ++r, ++m) { 5704 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5705 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5706 remotePointsNew[m].rank = rrank; 5707 } 5708 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5709 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5710 remotePointsNew[m].rank = rrank; 5711 ++m; 5712 } else if ((p >= fMax) && (p < fEnd)) { 5713 /* Old hybrid faces stay the same */ 5714 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5715 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5716 remotePointsNew[m].rank = rrank; 5717 ++m; 5718 } else if ((p >= cStart) && (p < cMax)) { 5719 /* Old interior cells add new cells and interior faces */ 5720 for (r = 0; r < 4; ++r, ++m) { 5721 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5722 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5723 remotePointsNew[m].rank = rrank; 5724 } 5725 for (r = 0; r < 3; ++r, ++m) { 5726 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5727 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5728 remotePointsNew[m].rank = rrank; 5729 } 5730 } else if ((p >= cMax) && (p < cEnd)) { 5731 /* Old hybrid cells add new cells and hybrid face */ 5732 for (r = 0; r < 2; ++r, ++m) { 5733 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5734 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5735 remotePointsNew[m].rank = rrank; 5736 } 5737 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5738 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]); 5739 remotePointsNew[m].rank = rrank; 5740 ++m; 5741 } 5742 break; 5743 case 2: 5744 case 4: 5745 /* Hybrid Hex 2D */ 5746 if ((p >= vStart) && (p < vEnd)) { 5747 /* Old vertices stay the same */ 5748 localPointsNew[m] = vStartNew + (p - vStart); 5749 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5750 remotePointsNew[m].rank = rrank; 5751 ++m; 5752 } else if ((p >= fStart) && (p < fMax)) { 5753 /* Old interior faces add new faces and vertex */ 5754 for (r = 0; r < 2; ++r, ++m) { 5755 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5756 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5757 remotePointsNew[m].rank = rrank; 5758 } 5759 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5760 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5761 remotePointsNew[m].rank = rrank; 5762 ++m; 5763 } else if ((p >= fMax) && (p < fEnd)) { 5764 /* Old hybrid faces stay the same */ 5765 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5766 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5767 remotePointsNew[m].rank = rrank; 5768 ++m; 5769 } else if ((p >= cStart) && (p < cMax)) { 5770 /* Old interior cells add new cells, interior faces, and vertex */ 5771 for (r = 0; r < 4; ++r, ++m) { 5772 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5773 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5774 remotePointsNew[m].rank = rrank; 5775 } 5776 for (r = 0; r < 4; ++r, ++m) { 5777 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5778 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5779 remotePointsNew[m].rank = rrank; 5780 } 5781 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 5782 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 5783 remotePointsNew[m].rank = rrank; 5784 ++m; 5785 } else if ((p >= cStart) && (p < cMax)) { 5786 /* Old hybrid cells add new cells and hybrid face */ 5787 for (r = 0; r < 2; ++r, ++m) { 5788 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5789 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5790 remotePointsNew[m].rank = rrank; 5791 } 5792 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5793 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]); 5794 remotePointsNew[m].rank = rrank; 5795 ++m; 5796 } 5797 break; 5798 case 5: 5799 case 7: 5800 /* Hybrid Simplicial 3D */ 5801 if ((p >= vStart) && (p < vEnd)) { 5802 /* Interior vertices stay the same */ 5803 localPointsNew[m] = vStartNew + (p - vStart); 5804 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5805 remotePointsNew[m].rank = rrank; 5806 ++m; 5807 } else if ((p >= eStart) && (p < eMax)) { 5808 /* Interior edges add new edges and vertex */ 5809 for (r = 0; r < 2; ++r, ++m) { 5810 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5811 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5812 remotePointsNew[m].rank = rrank; 5813 } 5814 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5815 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5816 remotePointsNew[m].rank = rrank; 5817 ++m; 5818 } else if ((p >= eMax) && (p < eEnd)) { 5819 /* Hybrid edges stay the same */ 5820 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5821 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]); 5822 remotePointsNew[m].rank = rrank; 5823 ++m; 5824 } else if ((p >= fStart) && (p < fMax)) { 5825 /* Interior faces add new faces and edges */ 5826 for (r = 0; r < 4; ++r, ++m) { 5827 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5828 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5829 remotePointsNew[m].rank = rrank; 5830 } 5831 for (r = 0; r < 3; ++r, ++m) { 5832 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5833 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5834 remotePointsNew[m].rank = rrank; 5835 } 5836 } else if ((p >= fMax) && (p < fEnd)) { 5837 /* Hybrid faces add new faces and edges */ 5838 for (r = 0; r < 2; ++r, ++m) { 5839 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5840 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; 5841 remotePointsNew[m].rank = rrank; 5842 } 5843 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 5844 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]); 5845 remotePointsNew[m].rank = rrank; 5846 ++m; 5847 } else if ((p >= cStart) && (p < cMax)) { 5848 /* Interior cells add new cells, faces, and edges */ 5849 for (r = 0; r < 8; ++r, ++m) { 5850 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5851 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5852 remotePointsNew[m].rank = rrank; 5853 } 5854 for (r = 0; r < 8; ++r, ++m) { 5855 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5856 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 5857 remotePointsNew[m].rank = rrank; 5858 } 5859 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 5860 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; 5861 remotePointsNew[m].rank = rrank; 5862 ++m; 5863 } else if ((p >= cMax) && (p < cEnd)) { 5864 /* Hybrid cells add new cells and faces */ 5865 for (r = 0; r < 4; ++r, ++m) { 5866 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5867 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5868 remotePointsNew[m].rank = rrank; 5869 } 5870 for (r = 0; r < 3; ++r, ++m) { 5871 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5872 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; 5873 remotePointsNew[m].rank = rrank; 5874 } 5875 } 5876 break; 5877 case 6: 5878 case 8: 5879 /* Hybrid Hex 3D */ 5880 if ((p >= vStart) && (p < vEnd)) { 5881 /* Interior vertices stay the same */ 5882 localPointsNew[m] = vStartNew + (p - vStart); 5883 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5884 remotePointsNew[m].rank = rrank; 5885 ++m; 5886 } else if ((p >= eStart) && (p < eMax)) { 5887 /* Interior edges add new edges and vertex */ 5888 for (r = 0; r < 2; ++r, ++m) { 5889 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5890 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5891 remotePointsNew[m].rank = rrank; 5892 } 5893 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5894 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5895 remotePointsNew[m].rank = rrank; 5896 ++m; 5897 } else if ((p >= eMax) && (p < eEnd)) { 5898 /* Hybrid edges stay the same */ 5899 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 5900 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+1]); 5901 remotePointsNew[m].rank = rrank; 5902 ++m; 5903 } else if ((p >= fStart) && (p < fMax)) { 5904 /* Interior faces add new faces, edges, and vertex */ 5905 for (r = 0; r < 4; ++r, ++m) { 5906 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5907 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5908 remotePointsNew[m].rank = rrank; 5909 } 5910 for (r = 0; r < 4; ++r, ++m) { 5911 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 5912 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 5913 remotePointsNew[m].rank = rrank; 5914 } 5915 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 5916 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 5917 remotePointsNew[m].rank = rrank; 5918 ++m; 5919 } else if ((p >= fMax) && (p < fEnd)) { 5920 /* Hybrid faces add new faces and edges */ 5921 for (r = 0; r < 2; ++r, ++m) { 5922 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 5923 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 5924 remotePointsNew[m].rank = rrank; 5925 } 5926 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 5927 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5928 remotePointsNew[m].rank = rrank; 5929 ++m; 5930 } else if ((p >= cStart) && (p < cMax)) { 5931 /* Interior cells add new cells, faces, edges, and vertex */ 5932 for (r = 0; r < 8; ++r, ++m) { 5933 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5934 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5935 remotePointsNew[m].rank = rrank; 5936 } 5937 for (r = 0; r < 12; ++r, ++m) { 5938 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 5939 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 5940 remotePointsNew[m].rank = rrank; 5941 } 5942 for (r = 0; r < 6; ++r, ++m) { 5943 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 5944 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; 5945 remotePointsNew[m].rank = rrank; 5946 } 5947 for (r = 0; r < 1; ++r, ++m) { 5948 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 5949 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 5950 remotePointsNew[m].rank = rrank; 5951 } 5952 } else if ((p >= cMax) && (p < cEnd)) { 5953 /* Hybrid cells add new cells, faces, and edges */ 5954 for (r = 0; r < 4; ++r, ++m) { 5955 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5956 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5957 remotePointsNew[m].rank = rrank; 5958 } 5959 for (r = 0; r < 4; ++r, ++m) { 5960 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 5961 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5962 remotePointsNew[m].rank = rrank; 5963 } 5964 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 5965 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]); 5966 remotePointsNew[m].rank = rrank; 5967 ++m; 5968 } 5969 break; 5970 default: 5971 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5972 } 5973 } 5974 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 5975 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 5976 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 5977 { 5978 PetscSFNode *rp, *rtmp; 5979 PetscInt *lp, *idx, *ltmp, i; 5980 5981 /* SF needs sorted leaves to correct calculate Gather */ 5982 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 5983 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 5984 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 5985 for (i = 0; i < numLeavesNew; ++i) idx[i] = i; 5986 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 5987 for (i = 0; i < numLeavesNew; ++i) { 5988 lp[i] = localPointsNew[idx[i]]; 5989 rp[i] = remotePointsNew[idx[i]]; 5990 } 5991 ltmp = localPointsNew; 5992 localPointsNew = lp; 5993 rtmp = remotePointsNew; 5994 remotePointsNew = rp; 5995 ierr = PetscFree(idx);CHKERRQ(ierr); 5996 ierr = PetscFree(ltmp);CHKERRQ(ierr); 5997 ierr = PetscFree(rtmp);CHKERRQ(ierr); 5998 } 5999 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6000 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6001 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6002 PetscFunctionReturn(0); 6003 } 6004 6005 #undef __FUNCT__ 6006 #define __FUNCT__ "CellRefinerCreateLabels" 6007 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6008 { 6009 PetscInt numLabels, l; 6010 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6011 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6012 PetscErrorCode ierr; 6013 6014 PetscFunctionBegin; 6015 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6016 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6017 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6018 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6019 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6020 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6021 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6022 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6023 switch (refiner) { 6024 case 0: break; 6025 case 7: 6026 case 8: 6027 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6028 case 3: 6029 case 4: 6030 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6031 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6032 } 6033 for (l = 0; l < numLabels; ++l) { 6034 DMLabel label, labelNew; 6035 const char *lname; 6036 PetscBool isDepth; 6037 IS valueIS; 6038 const PetscInt *values; 6039 PetscInt numValues, val; 6040 6041 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6042 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6043 if (isDepth) continue; 6044 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6045 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6046 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6047 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6048 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6049 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6050 for (val = 0; val < numValues; ++val) { 6051 IS pointIS; 6052 const PetscInt *points; 6053 PetscInt numPoints, n; 6054 6055 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6056 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6057 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6058 for (n = 0; n < numPoints; ++n) { 6059 const PetscInt p = points[n]; 6060 switch (refiner) { 6061 case 1: 6062 /* Simplicial 2D */ 6063 if ((p >= vStart) && (p < vEnd)) { 6064 /* Old vertices stay the same */ 6065 newp = vStartNew + (p - vStart); 6066 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6067 } else if ((p >= fStart) && (p < fEnd)) { 6068 /* Old faces add new faces and vertex */ 6069 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6070 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6071 for (r = 0; r < 2; ++r) { 6072 newp = fStartNew + (p - fStart)*2 + r; 6073 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6074 } 6075 } else if ((p >= cStart) && (p < cEnd)) { 6076 /* Old cells add new cells and interior faces */ 6077 for (r = 0; r < 4; ++r) { 6078 newp = cStartNew + (p - cStart)*4 + r; 6079 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6080 } 6081 for (r = 0; r < 3; ++r) { 6082 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6083 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6084 } 6085 } 6086 break; 6087 case 2: 6088 /* Hex 2D */ 6089 if ((p >= vStart) && (p < vEnd)) { 6090 /* Old vertices stay the same */ 6091 newp = vStartNew + (p - vStart); 6092 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6093 } else if ((p >= fStart) && (p < fEnd)) { 6094 /* Old faces add new faces and vertex */ 6095 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6096 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6097 for (r = 0; r < 2; ++r) { 6098 newp = fStartNew + (p - fStart)*2 + r; 6099 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6100 } 6101 } else if ((p >= cStart) && (p < cEnd)) { 6102 /* Old cells add new cells and interior faces and vertex */ 6103 for (r = 0; r < 4; ++r) { 6104 newp = cStartNew + (p - cStart)*4 + r; 6105 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6106 } 6107 for (r = 0; r < 4; ++r) { 6108 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6109 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6110 } 6111 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6112 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6113 } 6114 break; 6115 case 3: 6116 /* Hybrid simplicial 2D */ 6117 if ((p >= vStart) && (p < vEnd)) { 6118 /* Old vertices stay the same */ 6119 newp = vStartNew + (p - vStart); 6120 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6121 } else if ((p >= fStart) && (p < fMax)) { 6122 /* Old interior faces add new faces and vertex */ 6123 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6124 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6125 for (r = 0; r < 2; ++r) { 6126 newp = fStartNew + (p - fStart)*2 + r; 6127 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6128 } 6129 } else if ((p >= fMax) && (p < fEnd)) { 6130 /* Old hybrid faces stay the same */ 6131 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6132 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6133 } else if ((p >= cStart) && (p < cMax)) { 6134 /* Old interior cells add new cells and interior faces */ 6135 for (r = 0; r < 4; ++r) { 6136 newp = cStartNew + (p - cStart)*4 + r; 6137 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6138 } 6139 for (r = 0; r < 3; ++r) { 6140 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6141 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6142 } 6143 } else if ((p >= cMax) && (p < cEnd)) { 6144 /* Old hybrid cells add new cells and hybrid face */ 6145 for (r = 0; r < 2; ++r) { 6146 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6147 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6148 } 6149 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6150 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6151 } 6152 break; 6153 case 4: 6154 /* Hybrid Hex 2D */ 6155 if ((p >= vStart) && (p < vEnd)) { 6156 /* Old vertices stay the same */ 6157 newp = vStartNew + (p - vStart); 6158 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6159 } else if ((p >= fStart) && (p < fMax)) { 6160 /* Old interior faces add new faces and vertex */ 6161 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6162 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6163 for (r = 0; r < 2; ++r) { 6164 newp = fStartNew + (p - fStart)*2 + r; 6165 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6166 } 6167 } else if ((p >= fMax) && (p < fEnd)) { 6168 /* Old hybrid faces stay the same */ 6169 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6170 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6171 } else if ((p >= cStart) && (p < cMax)) { 6172 /* Old interior cells add new cells, interior faces, and vertex */ 6173 for (r = 0; r < 4; ++r) { 6174 newp = cStartNew + (p - cStart)*4 + r; 6175 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6176 } 6177 for (r = 0; r < 4; ++r) { 6178 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6179 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6180 } 6181 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6182 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6183 } else if ((p >= cMax) && (p < cEnd)) { 6184 /* Old hybrid cells add new cells and hybrid face */ 6185 for (r = 0; r < 2; ++r) { 6186 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6187 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6188 } 6189 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6190 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6191 } 6192 break; 6193 case 5: 6194 /* Simplicial 3D */ 6195 if ((p >= vStart) && (p < vEnd)) { 6196 /* Old vertices stay the same */ 6197 newp = vStartNew + (p - vStart); 6198 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6199 } else if ((p >= eStart) && (p < eEnd)) { 6200 /* Old edges add new edges and vertex */ 6201 for (r = 0; r < 2; ++r) { 6202 newp = eStartNew + (p - eStart)*2 + r; 6203 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6204 } 6205 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6206 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6207 } else if ((p >= fStart) && (p < fEnd)) { 6208 /* Old faces add new faces and edges */ 6209 for (r = 0; r < 4; ++r) { 6210 newp = fStartNew + (p - fStart)*4 + r; 6211 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6212 } 6213 for (r = 0; r < 3; ++r) { 6214 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6215 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6216 } 6217 } else if ((p >= cStart) && (p < cEnd)) { 6218 /* Old cells add new cells and interior faces and edges */ 6219 for (r = 0; r < 8; ++r) { 6220 newp = cStartNew + (p - cStart)*8 + r; 6221 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6222 } 6223 for (r = 0; r < 8; ++r) { 6224 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6225 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6226 } 6227 for (r = 0; r < 1; ++r) { 6228 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6229 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6230 } 6231 } 6232 break; 6233 case 7: 6234 /* Hybrid Simplicial 3D */ 6235 if ((p >= vStart) && (p < vEnd)) { 6236 /* Interior vertices stay the same */ 6237 newp = vStartNew + (p - vStart); 6238 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6239 } else if ((p >= eStart) && (p < eMax)) { 6240 /* Interior edges add new edges and vertex */ 6241 for (r = 0; r < 2; ++r) { 6242 newp = eStartNew + (p - eStart)*2 + r; 6243 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6244 } 6245 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6246 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6247 } else if ((p >= eMax) && (p < eEnd)) { 6248 /* Hybrid edges stay the same */ 6249 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6250 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6251 } else if ((p >= fStart) && (p < fMax)) { 6252 /* Interior faces add new faces and edges */ 6253 for (r = 0; r < 4; ++r) { 6254 newp = fStartNew + (p - fStart)*4 + r; 6255 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6256 } 6257 for (r = 0; r < 3; ++r) { 6258 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6259 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6260 } 6261 } else if ((p >= fMax) && (p < fEnd)) { 6262 /* Hybrid faces add new faces and edges */ 6263 for (r = 0; r < 2; ++r) { 6264 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6265 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6266 } 6267 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6268 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6269 } else if ((p >= cStart) && (p < cMax)) { 6270 /* Interior cells add new cells, faces, and edges */ 6271 for (r = 0; r < 8; ++r) { 6272 newp = cStartNew + (p - cStart)*8 + r; 6273 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6274 } 6275 for (r = 0; r < 8; ++r) { 6276 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6277 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6278 } 6279 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6280 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6281 } else if ((p >= cMax) && (p < cEnd)) { 6282 /* Hybrid cells add new cells and faces */ 6283 for (r = 0; r < 4; ++r) { 6284 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6285 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6286 } 6287 for (r = 0; r < 3; ++r) { 6288 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6289 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6290 } 6291 } 6292 break; 6293 case 6: 6294 /* Hex 3D */ 6295 if ((p >= vStart) && (p < vEnd)) { 6296 /* Old vertices stay the same */ 6297 newp = vStartNew + (p - vStart); 6298 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6299 } else if ((p >= eStart) && (p < eEnd)) { 6300 /* Old edges add new edges and vertex */ 6301 for (r = 0; r < 2; ++r) { 6302 newp = eStartNew + (p - eStart)*2 + r; 6303 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6304 } 6305 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6306 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6307 } else if ((p >= fStart) && (p < fEnd)) { 6308 /* Old faces add new faces, edges, and vertex */ 6309 for (r = 0; r < 4; ++r) { 6310 newp = fStartNew + (p - fStart)*4 + r; 6311 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6312 } 6313 for (r = 0; r < 4; ++r) { 6314 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6315 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6316 } 6317 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6318 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6319 } else if ((p >= cStart) && (p < cEnd)) { 6320 /* Old cells add new cells, faces, edges, and vertex */ 6321 for (r = 0; r < 8; ++r) { 6322 newp = cStartNew + (p - cStart)*8 + r; 6323 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6324 } 6325 for (r = 0; r < 12; ++r) { 6326 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6327 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6328 } 6329 for (r = 0; r < 6; ++r) { 6330 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6331 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6332 } 6333 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6334 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6335 } 6336 break; 6337 case 8: 6338 /* Hybrid Hex 3D */ 6339 if ((p >= vStart) && (p < vEnd)) { 6340 /* Interior vertices stay the same */ 6341 newp = vStartNew + (p - vStart); 6342 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6343 } else if ((p >= eStart) && (p < eMax)) { 6344 /* Interior edges add new edges and vertex */ 6345 for (r = 0; r < 2; ++r) { 6346 newp = eStartNew + (p - eStart)*2 + r; 6347 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6348 } 6349 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6350 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6351 } else if ((p >= eMax) && (p < eEnd)) { 6352 /* Hybrid edges stay the same */ 6353 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6354 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6355 } else if ((p >= fStart) && (p < fMax)) { 6356 /* Interior faces add new faces, edges, and vertex */ 6357 for (r = 0; r < 4; ++r) { 6358 newp = fStartNew + (p - fStart)*4 + r; 6359 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6360 } 6361 for (r = 0; r < 4; ++r) { 6362 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6363 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6364 } 6365 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6366 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6367 } else if ((p >= fMax) && (p < fEnd)) { 6368 /* Hybrid faces add new faces and edges */ 6369 for (r = 0; r < 2; ++r) { 6370 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6371 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6372 } 6373 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6374 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6375 } else if ((p >= cStart) && (p < cMax)) { 6376 /* Interior cells add new cells, faces, edges, and vertex */ 6377 for (r = 0; r < 8; ++r) { 6378 newp = cStartNew + (p - cStart)*8 + r; 6379 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6380 } 6381 for (r = 0; r < 12; ++r) { 6382 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6383 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6384 } 6385 for (r = 0; r < 6; ++r) { 6386 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6387 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6388 } 6389 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6390 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6391 } else if ((p >= cMax) && (p < cEnd)) { 6392 /* Hybrid cells add new cells, faces, and edges */ 6393 for (r = 0; r < 4; ++r) { 6394 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6395 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6396 } 6397 for (r = 0; r < 4; ++r) { 6398 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6399 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6400 } 6401 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6402 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6403 } 6404 break; 6405 default: 6406 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6407 } 6408 } 6409 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6410 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6411 } 6412 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6413 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6414 if (0) { 6415 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6416 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6417 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6418 } 6419 } 6420 PetscFunctionReturn(0); 6421 } 6422 6423 #undef __FUNCT__ 6424 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6425 /* This will only work for interpolated meshes */ 6426 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6427 { 6428 DM rdm; 6429 PetscInt *depthSize; 6430 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6431 PetscErrorCode ierr; 6432 6433 PetscFunctionBegin; 6434 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6435 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6436 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6437 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 6438 /* Calculate number of new points of each depth */ 6439 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6440 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6441 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6442 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6443 /* Step 1: Set chart */ 6444 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6445 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6446 /* Step 2: Set cone/support sizes */ 6447 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6448 /* Step 3: Setup refined DM */ 6449 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6450 /* Step 4: Set cones and supports */ 6451 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6452 /* Step 5: Stratify */ 6453 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6454 /* Step 6: Set coordinates for vertices */ 6455 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6456 /* Step 7: Create pointSF */ 6457 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6458 /* Step 8: Create labels */ 6459 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6460 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6461 6462 *dmRefined = rdm; 6463 PetscFunctionReturn(0); 6464 } 6465 6466 #undef __FUNCT__ 6467 #define __FUNCT__ "DMPlexCreateCoarsePointIS" 6468 /*@ 6469 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 6470 6471 Input Parameter: 6472 . dm - The coarse DM 6473 6474 Output Parameter: 6475 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 6476 6477 Level: developer 6478 6479 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 6480 @*/ 6481 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 6482 { 6483 CellRefiner cellRefiner; 6484 PetscInt *depthSize, *fpoints; 6485 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6486 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 6487 PetscErrorCode ierr; 6488 6489 PetscFunctionBegin; 6490 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6491 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6492 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6493 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 6494 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6495 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6496 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6497 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 6498 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 6499 switch (cellRefiner) { 6500 case 1: /* Simplicial 2D */ 6501 case 3: /* Hybrid simplicial 2D */ 6502 case 2: /* Hex 2D */ 6503 case 4: /* Hybrid Hex 2D */ 6504 case 5: /* Simplicial 3D */ 6505 case 7: /* Hybrid Simplicial 3D */ 6506 case 6: /* Hex 3D */ 6507 case 8: /* Hybrid Hex 3D */ 6508 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 6509 break; 6510 default: 6511 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 6512 } 6513 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 6514 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6515 PetscFunctionReturn(0); 6516 } 6517 6518 #undef __FUNCT__ 6519 #define __FUNCT__ "DMPlexSetRefinementUniform" 6520 /*@ 6521 DMPlexSetRefinementUniform - Set the flag for uniform refinement 6522 6523 Input Parameters: 6524 + dm - The DM 6525 - refinementUniform - The flag for uniform refinement 6526 6527 Level: developer 6528 6529 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6530 @*/ 6531 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6532 { 6533 DM_Plex *mesh = (DM_Plex*) dm->data; 6534 6535 PetscFunctionBegin; 6536 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6537 mesh->refinementUniform = refinementUniform; 6538 PetscFunctionReturn(0); 6539 } 6540 6541 #undef __FUNCT__ 6542 #define __FUNCT__ "DMPlexGetRefinementUniform" 6543 /*@ 6544 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 6545 6546 Input Parameter: 6547 . dm - The DM 6548 6549 Output Parameter: 6550 . refinementUniform - The flag for uniform refinement 6551 6552 Level: developer 6553 6554 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6555 @*/ 6556 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6557 { 6558 DM_Plex *mesh = (DM_Plex*) dm->data; 6559 6560 PetscFunctionBegin; 6561 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6562 PetscValidPointer(refinementUniform, 2); 6563 *refinementUniform = mesh->refinementUniform; 6564 PetscFunctionReturn(0); 6565 } 6566 6567 #undef __FUNCT__ 6568 #define __FUNCT__ "DMPlexSetRefinementLimit" 6569 /*@ 6570 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 6571 6572 Input Parameters: 6573 + dm - The DM 6574 - refinementLimit - The maximum cell volume in the refined mesh 6575 6576 Level: developer 6577 6578 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6579 @*/ 6580 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6581 { 6582 DM_Plex *mesh = (DM_Plex*) dm->data; 6583 6584 PetscFunctionBegin; 6585 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6586 mesh->refinementLimit = refinementLimit; 6587 PetscFunctionReturn(0); 6588 } 6589 6590 #undef __FUNCT__ 6591 #define __FUNCT__ "DMPlexGetRefinementLimit" 6592 /*@ 6593 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 6594 6595 Input Parameter: 6596 . dm - The DM 6597 6598 Output Parameter: 6599 . refinementLimit - The maximum cell volume in the refined mesh 6600 6601 Level: developer 6602 6603 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6604 @*/ 6605 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6606 { 6607 DM_Plex *mesh = (DM_Plex*) dm->data; 6608 6609 PetscFunctionBegin; 6610 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6611 PetscValidPointer(refinementLimit, 2); 6612 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6613 *refinementLimit = mesh->refinementLimit; 6614 PetscFunctionReturn(0); 6615 } 6616 6617 #undef __FUNCT__ 6618 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6619 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6620 { 6621 PetscInt dim, cStart, cEnd, coneSize, cMax; 6622 PetscErrorCode ierr; 6623 6624 PetscFunctionBegin; 6625 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6626 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6627 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 6628 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6629 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6630 switch (dim) { 6631 case 2: 6632 switch (coneSize) { 6633 case 3: 6634 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 6635 else *cellRefiner = 1; /* Triangular */ 6636 break; 6637 case 4: 6638 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 6639 else *cellRefiner = 2; /* Quadrilateral */ 6640 break; 6641 default: 6642 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6643 } 6644 break; 6645 case 3: 6646 switch (coneSize) { 6647 case 4: 6648 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 6649 else *cellRefiner = 5; /* Tetrahedral */ 6650 break; 6651 case 6: 6652 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 6653 else *cellRefiner = 6; /* hexahedral */ 6654 break; 6655 default: 6656 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6657 } 6658 break; 6659 default: 6660 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6661 } 6662 PetscFunctionReturn(0); 6663 } 6664