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]; 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 for (r = 0; r < 4; ++r) { 4584 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4585 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4586 PetscInt edgeB = (edgeA+3)%4; 4587 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]); 4588 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4589 orntNew[0] = ornt[0]; 4590 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4591 orntNew[1] = ornt[0]; 4592 coneNew[(r+0)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeA+2] - fMax)*2 + (fornt[edgeA] < 0 ? 1 : 0); 4593 orntNew[(r+0)%4+2] = ornt[edgeA]; 4594 coneNew[(r+1)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4595 orntNew[(r+1)%4+2] = 0; 4596 coneNew[(r+2)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4597 orntNew[(r+2)%4+2] = -2; 4598 coneNew[(r+3)%4+2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[edgeB+2] - fMax)*2 + (fornt[edgeB] < 0 ? 0 : 1); 4599 orntNew[(r+3)%4+2] = ornt[edgeB]; 4600 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4601 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4602 #if 1 4603 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); 4604 for (p = 0; p < 2; ++p) { 4605 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); 4606 } 4607 for (p = 2; p < 6; ++p) { 4608 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); 4609 } 4610 #endif 4611 } 4612 } 4613 /* Interior split faces have 4 edges and the same cells as the parent */ 4614 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4615 ierr = PetscMalloc1((4 + maxSupportSize*2), &supportRef);CHKERRQ(ierr); 4616 for (f = fStart; f < fMax; ++f) { 4617 for (r = 0; r < 4; ++r) { 4618 /* TODO: This can come from GetFaces_Internal() */ 4619 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}; 4620 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4621 const PetscInt *cone, *ornt, *support; 4622 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4623 4624 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4625 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4626 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4627 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4628 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4629 orntNew[(r+0)%4] = ornt[r]; 4630 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4631 orntNew[(r+1)%4] = 0; 4632 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4633 orntNew[(r+2)%4] = -2; 4634 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4635 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4636 #if 1 4637 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4638 for (p = 0; p < 4; ++p) { 4639 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); 4640 } 4641 #endif 4642 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4643 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4644 for (s = 0; s < supportSize; ++s) { 4645 PetscInt subf; 4646 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4647 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4648 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4649 for (c = 0; c < coneSize; ++c) { 4650 if (cone[c] == f) break; 4651 } 4652 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4653 if (support[s] < cMax) { 4654 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4655 } else { 4656 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4657 } 4658 } 4659 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4660 #if 1 4661 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4662 for (p = 0; p < supportSize; ++p) { 4663 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); 4664 } 4665 #endif 4666 } 4667 } 4668 /* Interior faces have 4 edges and 2 cells */ 4669 for (c = cStart; c < cMax; ++c) { 4670 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}; 4671 const PetscInt *cone, *ornt; 4672 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4673 4674 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4675 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4676 /* A-D face */ 4677 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4678 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4679 orntNew[0] = 0; 4680 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4681 orntNew[1] = 0; 4682 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4683 orntNew[2] = -2; 4684 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4685 orntNew[3] = -2; 4686 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4687 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4688 #if 1 4689 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4690 for (p = 0; p < 4; ++p) { 4691 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); 4692 } 4693 #endif 4694 /* C-D face */ 4695 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4696 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4697 orntNew[0] = 0; 4698 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4699 orntNew[1] = 0; 4700 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4701 orntNew[2] = -2; 4702 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4703 orntNew[3] = -2; 4704 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4705 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4706 #if 1 4707 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4708 for (p = 0; p < 4; ++p) { 4709 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); 4710 } 4711 #endif 4712 /* B-C face */ 4713 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4714 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4715 orntNew[0] = -2; 4716 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4717 orntNew[1] = 0; 4718 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4719 orntNew[2] = 0; 4720 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4721 orntNew[3] = -2; 4722 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4723 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4724 #if 1 4725 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4726 for (p = 0; p < 4; ++p) { 4727 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4728 } 4729 #endif 4730 /* A-B face */ 4731 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4732 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4733 orntNew[0] = -2; 4734 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4735 orntNew[1] = 0; 4736 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4737 orntNew[2] = 0; 4738 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4739 orntNew[3] = -2; 4740 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4741 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4742 #if 1 4743 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4744 for (p = 0; p < 4; ++p) { 4745 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); 4746 } 4747 #endif 4748 /* E-F face */ 4749 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4750 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4751 orntNew[0] = -2; 4752 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4753 orntNew[1] = -2; 4754 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4755 orntNew[2] = 0; 4756 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4757 orntNew[3] = 0; 4758 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4759 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4760 #if 1 4761 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4762 for (p = 0; p < 4; ++p) { 4763 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); 4764 } 4765 #endif 4766 /* F-G face */ 4767 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4768 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4769 orntNew[0] = -2; 4770 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4771 orntNew[1] = -2; 4772 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4773 orntNew[2] = 0; 4774 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4775 orntNew[3] = 0; 4776 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4777 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4778 #if 1 4779 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4780 for (p = 0; p < 4; ++p) { 4781 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); 4782 } 4783 #endif 4784 /* G-H face */ 4785 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4786 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4787 orntNew[0] = -2; 4788 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4789 orntNew[1] = 0; 4790 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4791 orntNew[2] = 0; 4792 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4793 orntNew[3] = -2; 4794 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4795 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4796 #if 1 4797 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4798 for (p = 0; p < 4; ++p) { 4799 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); 4800 } 4801 #endif 4802 /* E-H face */ 4803 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4804 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4805 orntNew[0] = -2; 4806 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4807 orntNew[1] = -2; 4808 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4809 orntNew[2] = 0; 4810 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4811 orntNew[3] = 0; 4812 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4813 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4814 #if 1 4815 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4816 for (p = 0; p < 4; ++p) { 4817 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); 4818 } 4819 #endif 4820 /* A-E face */ 4821 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4822 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4823 orntNew[0] = 0; 4824 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4825 orntNew[1] = 0; 4826 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4827 orntNew[2] = -2; 4828 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4829 orntNew[3] = -2; 4830 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4831 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4832 #if 1 4833 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4834 for (p = 0; p < 4; ++p) { 4835 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); 4836 } 4837 #endif 4838 /* D-F face */ 4839 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4840 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4841 orntNew[0] = -2; 4842 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4843 orntNew[1] = 0; 4844 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4845 orntNew[2] = 0; 4846 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4847 orntNew[3] = -2; 4848 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4849 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4850 #if 1 4851 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4852 for (p = 0; p < 4; ++p) { 4853 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); 4854 } 4855 #endif 4856 /* C-G face */ 4857 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4858 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4859 orntNew[0] = -2; 4860 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4861 orntNew[1] = -2; 4862 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4863 orntNew[2] = 0; 4864 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4865 orntNew[3] = 0; 4866 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4867 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4868 #if 1 4869 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4870 for (p = 0; p < 4; ++p) { 4871 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); 4872 } 4873 #endif 4874 /* B-H face */ 4875 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 4876 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4877 orntNew[0] = 0; 4878 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4879 orntNew[1] = -2; 4880 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4881 orntNew[2] = -2; 4882 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4883 orntNew[3] = 0; 4884 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4885 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4886 #if 1 4887 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4888 for (p = 0; p < 4; ++p) { 4889 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); 4890 } 4891 #endif 4892 for (r = 0; r < 12; ++r) { 4893 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 4894 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4895 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4896 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4897 #if 1 4898 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4899 for (p = 0; p < 2; ++p) { 4900 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); 4901 } 4902 #endif 4903 } 4904 } 4905 /* Hybrid split faces have 4 edges and same cells */ 4906 for (f = fMax; f < fEnd; ++f) { 4907 const PetscInt *cone, *ornt, *support; 4908 PetscInt coneNew[4], orntNew[4]; 4909 PetscInt supportNew[2], size, s, c; 4910 4911 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4912 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4913 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4914 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4915 for (r = 0; r < 2; ++r) { 4916 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 4917 4918 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4919 orntNew[0] = ornt[0]; 4920 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4921 orntNew[1] = ornt[1]; 4922 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 4923 orntNew[2+r] = 0; 4924 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4925 orntNew[3-r] = 0; 4926 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4927 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4928 #if 1 4929 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4930 for (p = 0; p < 2; ++p) { 4931 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4932 } 4933 for (p = 2; p < 4; ++p) { 4934 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); 4935 } 4936 #endif 4937 for (s = 0; s < size; ++s) { 4938 const PetscInt *coneCell, *orntCell, *fornt; 4939 4940 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4941 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4942 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 4943 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 4944 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4945 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (fornt[c-2] < 0 ? 1-r : r))%4; 4946 } 4947 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4948 #if 1 4949 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4950 for (p = 0; p < size; ++p) { 4951 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); 4952 } 4953 #endif 4954 } 4955 } 4956 /* Hybrid cell faces have 4 edges and 2 cells */ 4957 for (c = cMax; c < cEnd; ++c) { 4958 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 4959 const PetscInt *cone, *ornt; 4960 PetscInt coneNew[4], orntNew[4]; 4961 PetscInt supportNew[2]; 4962 4963 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4964 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4965 for (r = 0; r < 4; ++r) { 4966 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 4967 orntNew[0] = 0; 4968 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 4969 orntNew[1] = 0; 4970 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 4971 orntNew[2] = 0; 4972 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 4973 orntNew[3] = 0; 4974 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4975 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4976 #if 1 4977 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); 4978 for (p = 0; p < 2; ++p) { 4979 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); 4980 } 4981 for (p = 2; p < 4; ++p) { 4982 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); 4983 } 4984 #endif 4985 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 4986 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 4987 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4988 #if 1 4989 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); 4990 for (p = 0; p < 2; ++p) { 4991 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); 4992 } 4993 #endif 4994 } 4995 } 4996 /* Interior split edges have 2 vertices and the same faces as the parent */ 4997 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4998 for (e = eStart; e < eMax; ++e) { 4999 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5000 5001 for (r = 0; r < 2; ++r) { 5002 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5003 const PetscInt *cone, *ornt, *support; 5004 PetscInt coneNew[2], coneSize, c, supportSize, s; 5005 5006 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5007 coneNew[0] = vStartNew + (cone[0] - vStart); 5008 coneNew[1] = vStartNew + (cone[1] - vStart); 5009 coneNew[(r+1)%2] = newv; 5010 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5011 #if 1 5012 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5013 for (p = 0; p < 2; ++p) { 5014 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); 5015 } 5016 #endif 5017 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5018 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5019 for (s = 0; s < supportSize; ++s) { 5020 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5021 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5022 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5023 for (c = 0; c < coneSize; ++c) { 5024 if (cone[c] == e) break; 5025 } 5026 if (support[s] < fMax) { 5027 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 5028 } else { 5029 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 5030 } 5031 } 5032 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5033 #if 1 5034 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5035 for (p = 0; p < supportSize; ++p) { 5036 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); 5037 } 5038 #endif 5039 } 5040 } 5041 /* Interior face edges have 2 vertices and 2+cells faces */ 5042 for (f = fStart; f < fMax; ++f) { 5043 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}; 5044 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5045 const PetscInt *cone, *coneCell, *orntCell, *support; 5046 PetscInt coneNew[2], coneSize, c, supportSize, s; 5047 5048 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5049 for (r = 0; r < 4; ++r) { 5050 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5051 5052 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5053 coneNew[1] = newv; 5054 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5055 #if 1 5056 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5057 for (p = 0; p < 2; ++p) { 5058 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); 5059 } 5060 #endif 5061 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5062 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5063 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5064 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5065 for (s = 0; s < supportSize; ++s) { 5066 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5067 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5068 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5069 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5070 if (support[s] < cMax) { 5071 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5072 } else { 5073 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadEdgeInverse_Static(orntCell[c], r); 5074 } 5075 } 5076 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5077 #if 1 5078 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5079 for (p = 0; p < 2+supportSize; ++p) { 5080 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); 5081 } 5082 #endif 5083 } 5084 } 5085 /* Interior cell edges have 2 vertices and 4 faces */ 5086 for (c = cStart; c < cMax; ++c) { 5087 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}; 5088 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5089 const PetscInt *cone; 5090 PetscInt coneNew[2], supportNew[4]; 5091 5092 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5093 for (r = 0; r < 6; ++r) { 5094 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5095 5096 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5097 coneNew[1] = newv; 5098 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5099 #if 1 5100 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5101 for (p = 0; p < 2; ++p) { 5102 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); 5103 } 5104 #endif 5105 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5106 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5107 #if 1 5108 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5109 for (p = 0; p < 4; ++p) { 5110 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); 5111 } 5112 #endif 5113 } 5114 } 5115 /* Hybrid edges have two vertices and the same faces */ 5116 for (e = eMax; e < eEnd; ++e) { 5117 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5118 const PetscInt *cone, *support, *fcone; 5119 PetscInt coneNew[2], size, fsize, s; 5120 5121 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5122 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5123 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5124 coneNew[0] = vStartNew + (cone[0] - vStart); 5125 coneNew[1] = vStartNew + (cone[1] - vStart); 5126 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5127 #if 1 5128 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5129 for (p = 0; p < 2; ++p) { 5130 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); 5131 } 5132 #endif 5133 for (s = 0; s < size; ++s) { 5134 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5135 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5136 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5137 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5138 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 5139 } 5140 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5141 #if 1 5142 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5143 for (p = 0; p < size; ++p) { 5144 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); 5145 } 5146 #endif 5147 } 5148 /* Hybrid face edges have 2 vertices and 2+cells faces */ 5149 for (f = fMax; f < fEnd; ++f) { 5150 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5151 const PetscInt *cone, *support, *ccone, *cornt; 5152 PetscInt coneNew[2], size, csize, s; 5153 5154 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5155 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5156 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5157 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5158 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 5159 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5160 #if 1 5161 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5162 for (p = 0; p < 2; ++p) { 5163 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); 5164 } 5165 #endif 5166 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 5167 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5168 for (s = 0; s < size; ++s) { 5169 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5170 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5171 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5172 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5173 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]); 5174 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + GetQuadSubfaceInverse_Static(cornt[0], c-2); 5175 } 5176 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5177 #if 1 5178 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5179 for (p = 0; p < 2+size; ++p) { 5180 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); 5181 } 5182 #endif 5183 } 5184 /* Hybrid cell edges have 2 vertices and 4 faces */ 5185 for (c = cMax; c < cEnd; ++c) { 5186 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5187 const PetscInt *cone, *support; 5188 PetscInt coneNew[2], size; 5189 5190 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5191 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5192 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5193 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5194 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5195 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5196 #if 1 5197 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5198 for (p = 0; p < 2; ++p) { 5199 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); 5200 } 5201 #endif 5202 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5203 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5204 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5205 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5206 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5207 #if 1 5208 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5209 for (p = 0; p < 4; ++p) { 5210 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); 5211 } 5212 #endif 5213 } 5214 /* Interior vertices have identical supports */ 5215 for (v = vStart; v < vEnd; ++v) { 5216 const PetscInt newp = vStartNew + (v - vStart); 5217 const PetscInt *support, *cone; 5218 PetscInt size, s; 5219 5220 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5221 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5222 for (s = 0; s < size; ++s) { 5223 PetscInt r = 0; 5224 5225 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5226 if (cone[1] == v) r = 1; 5227 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5228 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5229 } 5230 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5231 #if 1 5232 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5233 for (p = 0; p < size; ++p) { 5234 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); 5235 } 5236 #endif 5237 } 5238 /* Interior edge vertices have 2 + faces supports */ 5239 for (e = eStart; e < eMax; ++e) { 5240 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5241 const PetscInt *cone, *support; 5242 PetscInt size, s; 5243 5244 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5245 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5246 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5247 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5248 for (s = 0; s < size; ++s) { 5249 PetscInt r; 5250 5251 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5252 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5253 if (support[s] < fMax) { 5254 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5255 } else { 5256 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5257 } 5258 } 5259 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5260 #if 1 5261 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5262 for (p = 0; p < 2+size; ++p) { 5263 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); 5264 } 5265 #endif 5266 } 5267 /* Interior face vertices have 4 + cells supports */ 5268 for (f = fStart; f < fMax; ++f) { 5269 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5270 const PetscInt *cone, *support; 5271 PetscInt size, s; 5272 5273 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5274 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5275 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5276 for (s = 0; s < size; ++s) { 5277 PetscInt r; 5278 5279 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5280 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5281 if (support[s] < cMax) { 5282 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5283 } else { 5284 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5285 } 5286 } 5287 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5288 #if 1 5289 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5290 for (p = 0; p < 4+size; ++p) { 5291 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); 5292 } 5293 #endif 5294 } 5295 /* Cell vertices have 6 supports */ 5296 for (c = cStart; c < cMax; ++c) { 5297 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5298 PetscInt supportNew[6]; 5299 5300 for (r = 0; r < 6; ++r) { 5301 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5302 } 5303 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5304 } 5305 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5306 break; 5307 default: 5308 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5309 } 5310 PetscFunctionReturn(0); 5311 } 5312 5313 #undef __FUNCT__ 5314 #define __FUNCT__ "CellRefinerSetCoordinates" 5315 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5316 { 5317 PetscSection coordSection, coordSectionNew; 5318 Vec coordinates, coordinatesNew; 5319 PetscScalar *coords, *coordsNew; 5320 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5321 PetscInt dim, depth, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5322 PetscErrorCode ierr; 5323 5324 PetscFunctionBegin; 5325 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 5326 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5327 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5328 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5329 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5330 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5331 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5332 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5333 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5334 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5335 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5336 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5337 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, dim);CHKERRQ(ierr); 5338 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5339 if (cMax < 0) cMax = cEnd; 5340 if (fMax < 0) fMax = fEnd; 5341 if (eMax < 0) eMax = eEnd; 5342 /* All vertices have the dim coordinates */ 5343 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5344 ierr = PetscSectionSetDof(coordSectionNew, v, dim);CHKERRQ(ierr); 5345 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, dim);CHKERRQ(ierr); 5346 } 5347 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5348 ierr = DMSetCoordinateSection(rdm, coordSectionNew);CHKERRQ(ierr); 5349 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5350 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5351 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 5352 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5353 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5354 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 5355 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5356 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5357 switch (refiner) { 5358 case 0: break; 5359 case 6: /* Hex 3D */ 5360 case 8: /* Hybrid Hex 3D */ 5361 /* Face vertices have the average of corner coordinates */ 5362 for (f = fStart; f < fMax; ++f) { 5363 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5364 PetscInt *cone = NULL; 5365 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5366 5367 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5368 for (p = 0; p < closureSize*2; p += 2) { 5369 const PetscInt point = cone[p]; 5370 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5371 } 5372 for (v = 0; v < coneSize; ++v) { 5373 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5374 } 5375 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5376 for (d = 0; d < dim; ++d) { 5377 coordsNew[offnew+d] = 0.0; 5378 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5379 coordsNew[offnew+d] /= coneSize; 5380 } 5381 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5382 } 5383 case 2: /* Hex 2D */ 5384 case 4: /* Hybrid Hex 2D */ 5385 /* Cell vertices have the average of corner coordinates */ 5386 for (c = cStart; c < cMax; ++c) { 5387 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 5388 PetscInt *cone = NULL; 5389 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5390 5391 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5392 for (p = 0; p < closureSize*2; p += 2) { 5393 const PetscInt point = cone[p]; 5394 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5395 } 5396 for (v = 0; v < coneSize; ++v) { 5397 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5398 } 5399 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5400 for (d = 0; d < dim; ++d) { 5401 coordsNew[offnew+d] = 0.0; 5402 for (v = 0; v < coneSize; ++v) coordsNew[offnew+d] += coords[off[v]+d]; 5403 coordsNew[offnew+d] /= coneSize; 5404 } 5405 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5406 } 5407 case 1: /* Simplicial 2D */ 5408 case 3: /* Hybrid Simplicial 2D */ 5409 case 5: /* Simplicial 3D */ 5410 case 7: /* Hybrid Simplicial 3D */ 5411 /* Edge vertices have the average of endpoint coordinates */ 5412 for (e = eStart; e < eMax; ++e) { 5413 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5414 const PetscInt *cone; 5415 PetscInt coneSize, offA, offB, offnew, d; 5416 5417 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5418 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5419 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5420 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5421 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5422 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5423 for (d = 0; d < dim; ++d) { 5424 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coords[offB+d]); 5425 } 5426 } 5427 /* Old vertices have the same coordinates */ 5428 for (v = vStart; v < vEnd; ++v) { 5429 const PetscInt newv = vStartNew + (v - vStart); 5430 PetscInt off, offnew, d; 5431 5432 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5433 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5434 for (d = 0; d < dim; ++d) { 5435 coordsNew[offnew+d] = coords[off+d]; 5436 } 5437 } 5438 break; 5439 default: 5440 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5441 } 5442 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5443 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5444 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5445 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5446 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5447 PetscFunctionReturn(0); 5448 } 5449 5450 #undef __FUNCT__ 5451 #define __FUNCT__ "DMPlexCreateProcessSF" 5452 static PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5453 { 5454 PetscInt numRoots, numLeaves, l; 5455 const PetscInt *localPoints; 5456 const PetscSFNode *remotePoints; 5457 PetscInt *localPointsNew; 5458 PetscSFNode *remotePointsNew; 5459 PetscInt *ranks, *ranksNew; 5460 PetscErrorCode ierr; 5461 5462 PetscFunctionBegin; 5463 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5464 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5465 for (l = 0; l < numLeaves; ++l) { 5466 ranks[l] = remotePoints[l].rank; 5467 } 5468 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5469 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5470 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5471 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5472 for (l = 0; l < numLeaves; ++l) { 5473 ranksNew[l] = ranks[l]; 5474 localPointsNew[l] = l; 5475 remotePointsNew[l].index = 0; 5476 remotePointsNew[l].rank = ranksNew[l]; 5477 } 5478 ierr = PetscFree(ranks);CHKERRQ(ierr); 5479 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr); 5480 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5481 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5482 ierr = PetscSFSetGraph(*sfProcess, 1, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5483 PetscFunctionReturn(0); 5484 } 5485 5486 #undef __FUNCT__ 5487 #define __FUNCT__ "CellRefinerCreateSF" 5488 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5489 { 5490 PetscSF sf, sfNew, sfProcess; 5491 IS processRanks; 5492 MPI_Datatype depthType; 5493 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5494 const PetscInt *localPoints, *neighbors; 5495 const PetscSFNode *remotePoints; 5496 PetscInt *localPointsNew; 5497 PetscSFNode *remotePointsNew; 5498 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5499 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5500 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5501 PetscErrorCode ierr; 5502 5503 PetscFunctionBegin; 5504 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5505 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5506 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5507 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5508 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5509 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5510 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5511 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5512 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5513 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5514 /* Caculate size of new SF */ 5515 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5516 if (numRoots < 0) PetscFunctionReturn(0); 5517 for (l = 0; l < numLeaves; ++l) { 5518 const PetscInt p = localPoints[l]; 5519 5520 switch (refiner) { 5521 case 1: 5522 /* Simplicial 2D */ 5523 if ((p >= vStart) && (p < vEnd)) { 5524 /* Old vertices stay the same */ 5525 ++numLeavesNew; 5526 } else if ((p >= fStart) && (p < fEnd)) { 5527 /* Old faces add new faces and vertex */ 5528 numLeavesNew += 2 + 1; 5529 } else if ((p >= cStart) && (p < cEnd)) { 5530 /* Old cells add new cells and interior faces */ 5531 numLeavesNew += 4 + 3; 5532 } 5533 break; 5534 case 3: 5535 /* Hybrid Simplicial 2D */ 5536 if ((p >= vStart) && (p < vEnd)) { 5537 /* Interior vertices stay the same */ 5538 ++numLeavesNew; 5539 } else if ((p >= fStart) && (p < fMax)) { 5540 /* Interior faces add new faces and vertex */ 5541 numLeavesNew += 2 + 1; 5542 } else if ((p >= fMax) && (p < fEnd)) { 5543 /* Hybrid faces stay the same */ 5544 ++numLeavesNew; 5545 } else if ((p >= cStart) && (p < cMax)) { 5546 /* Interior cells add new cells and interior faces */ 5547 numLeavesNew += 4 + 3; 5548 } else if ((p >= cMax) && (p < cEnd)) { 5549 /* Hybrid cells add new cells and hybrid face */ 5550 numLeavesNew += 2 + 1; 5551 } 5552 break; 5553 case 2: 5554 /* Hex 2D */ 5555 if ((p >= vStart) && (p < vEnd)) { 5556 /* Old vertices stay the same */ 5557 ++numLeavesNew; 5558 } else if ((p >= fStart) && (p < fEnd)) { 5559 /* Old faces add new faces and vertex */ 5560 numLeavesNew += 2 + 1; 5561 } else if ((p >= cStart) && (p < cEnd)) { 5562 /* Old cells add new cells, interior faces, and vertex */ 5563 numLeavesNew += 4 + 4 + 1; 5564 } 5565 break; 5566 case 4: 5567 /* Hybrid Hex 2D */ 5568 if ((p >= vStart) && (p < vEnd)) { 5569 /* Interior vertices stay the same */ 5570 ++numLeavesNew; 5571 } else if ((p >= fStart) && (p < fMax)) { 5572 /* Interior faces add new faces and vertex */ 5573 numLeavesNew += 2 + 1; 5574 } else if ((p >= fMax) && (p < fEnd)) { 5575 /* Hybrid faces stay the same */ 5576 ++numLeavesNew; 5577 } else if ((p >= cStart) && (p < cMax)) { 5578 /* Interior cells add new cells, interior faces, and vertex */ 5579 numLeavesNew += 4 + 4 + 1; 5580 } else if ((p >= cMax) && (p < cEnd)) { 5581 /* Hybrid cells add new cells and hybrid face */ 5582 numLeavesNew += 2 + 1; 5583 } 5584 break; 5585 case 5: 5586 /* Simplicial 3D */ 5587 if ((p >= vStart) && (p < vEnd)) { 5588 /* Old vertices stay the same */ 5589 ++numLeavesNew; 5590 } else if ((p >= eStart) && (p < eEnd)) { 5591 /* Old edges add new edges and vertex */ 5592 numLeavesNew += 2 + 1; 5593 } else if ((p >= fStart) && (p < fEnd)) { 5594 /* Old faces add new faces and face edges */ 5595 numLeavesNew += 4 + 3; 5596 } else if ((p >= cStart) && (p < cEnd)) { 5597 /* Old cells add new cells and interior faces and edges */ 5598 numLeavesNew += 8 + 8 + 1; 5599 } 5600 break; 5601 case 7: 5602 /* Hybrid Simplicial 3D */ 5603 if ((p >= vStart) && (p < vEnd)) { 5604 /* Interior vertices stay the same */ 5605 ++numLeavesNew; 5606 } else if ((p >= eStart) && (p < eMax)) { 5607 /* Interior edges add new edges and vertex */ 5608 numLeavesNew += 2 + 1; 5609 } else if ((p >= eMax) && (p < eEnd)) { 5610 /* Hybrid edges stay the same */ 5611 ++numLeavesNew; 5612 } else if ((p >= fStart) && (p < fMax)) { 5613 /* Interior faces add new faces and edges */ 5614 numLeavesNew += 4 + 3; 5615 } else if ((p >= fMax) && (p < fEnd)) { 5616 /* Hybrid faces add new faces and edges */ 5617 numLeavesNew += 2 + 1; 5618 } else if ((p >= cStart) && (p < cMax)) { 5619 /* Interior cells add new cells, faces, and edges */ 5620 numLeavesNew += 8 + 8 + 1; 5621 } else if ((p >= cMax) && (p < cEnd)) { 5622 /* Hybrid cells add new cells and faces */ 5623 numLeavesNew += 4 + 3; 5624 } 5625 break; 5626 case 6: 5627 /* Hex 3D */ 5628 if ((p >= vStart) && (p < vEnd)) { 5629 /* Old vertices stay the same */ 5630 ++numLeavesNew; 5631 } else if ((p >= eStart) && (p < eEnd)) { 5632 /* Old edges add new edges, and vertex */ 5633 numLeavesNew += 2 + 1; 5634 } else if ((p >= fStart) && (p < fEnd)) { 5635 /* Old faces add new faces, edges, and vertex */ 5636 numLeavesNew += 4 + 4 + 1; 5637 } else if ((p >= cStart) && (p < cEnd)) { 5638 /* Old cells add new cells, faces, edges, and vertex */ 5639 numLeavesNew += 8 + 12 + 6 + 1; 5640 } 5641 break; 5642 case 8: 5643 /* Hybrid Hex 3D */ 5644 if ((p >= vStart) && (p < vEnd)) { 5645 /* Old vertices stay the same */ 5646 ++numLeavesNew; 5647 } else if ((p >= eStart) && (p < eMax)) { 5648 /* Interior edges add new edges, and vertex */ 5649 numLeavesNew += 2 + 1; 5650 } else if ((p >= eMax) && (p < eEnd)) { 5651 /* Hybrid edges stay the same */ 5652 ++numLeavesNew; 5653 } else if ((p >= fStart) && (p < fMax)) { 5654 /* Interior faces add new faces, edges, and vertex */ 5655 numLeavesNew += 4 + 4 + 1; 5656 } else if ((p >= fMax) && (p < fEnd)) { 5657 /* Hybrid faces add new faces and edges */ 5658 numLeavesNew += 2 + 1; 5659 } else if ((p >= cStart) && (p < cMax)) { 5660 /* Interior cells add new cells, faces, edges, and vertex */ 5661 numLeavesNew += 8 + 12 + 6 + 1; 5662 } else if ((p >= cStart) && (p < cEnd)) { 5663 /* Hybrid cells add new cells, faces, and edges */ 5664 numLeavesNew += 4 + 4 + 1; 5665 } 5666 break; 5667 default: 5668 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5669 } 5670 } 5671 /* Communicate depthSizes for each remote rank */ 5672 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5673 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5674 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5675 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5676 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5677 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5678 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5679 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5680 for (n = 0; n < numNeighbors; ++n) { 5681 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5682 } 5683 depthSizeOld[depth] = cMax; 5684 depthSizeOld[0] = vMax; 5685 depthSizeOld[depth-1] = fMax; 5686 depthSizeOld[1] = eMax; 5687 5688 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5689 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5690 5691 depthSizeOld[depth] = cEnd - cStart; 5692 depthSizeOld[0] = vEnd - vStart; 5693 depthSizeOld[depth-1] = fEnd - fStart; 5694 depthSizeOld[1] = eEnd - eStart; 5695 5696 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5697 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5698 for (n = 0; n < numNeighbors; ++n) { 5699 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5700 } 5701 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5702 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5703 /* Calculate new point SF */ 5704 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5705 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5706 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5707 for (l = 0, m = 0; l < numLeaves; ++l) { 5708 PetscInt p = localPoints[l]; 5709 PetscInt rp = remotePoints[l].index, n; 5710 PetscMPIInt rrank = remotePoints[l].rank; 5711 5712 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5713 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5714 switch (refiner) { 5715 case 1: 5716 /* Simplicial 2D */ 5717 if ((p >= vStart) && (p < vEnd)) { 5718 /* Old vertices stay the same */ 5719 localPointsNew[m] = vStartNew + (p - vStart); 5720 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5721 remotePointsNew[m].rank = rrank; 5722 ++m; 5723 } else if ((p >= fStart) && (p < fEnd)) { 5724 /* Old faces add new faces and vertex */ 5725 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5726 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5727 remotePointsNew[m].rank = rrank; 5728 ++m; 5729 for (r = 0; r < 2; ++r, ++m) { 5730 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5731 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5732 remotePointsNew[m].rank = rrank; 5733 } 5734 } else if ((p >= cStart) && (p < cEnd)) { 5735 /* Old cells add new cells and interior faces */ 5736 for (r = 0; r < 4; ++r, ++m) { 5737 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5738 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5739 remotePointsNew[m].rank = rrank; 5740 } 5741 for (r = 0; r < 3; ++r, ++m) { 5742 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 5743 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 5744 remotePointsNew[m].rank = rrank; 5745 } 5746 } 5747 break; 5748 case 2: 5749 /* Hex 2D */ 5750 if ((p >= vStart) && (p < vEnd)) { 5751 /* Old vertices stay the same */ 5752 localPointsNew[m] = vStartNew + (p - vStart); 5753 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5754 remotePointsNew[m].rank = rrank; 5755 ++m; 5756 } else if ((p >= fStart) && (p < fEnd)) { 5757 /* Old faces add new faces and vertex */ 5758 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5759 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5760 remotePointsNew[m].rank = rrank; 5761 ++m; 5762 for (r = 0; r < 2; ++r, ++m) { 5763 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5764 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5765 remotePointsNew[m].rank = rrank; 5766 } 5767 } else if ((p >= cStart) && (p < cEnd)) { 5768 /* Old cells add new cells, interior faces, and vertex */ 5769 for (r = 0; r < 4; ++r, ++m) { 5770 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5771 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5772 remotePointsNew[m].rank = rrank; 5773 } 5774 for (r = 0; r < 4; ++r, ++m) { 5775 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 5776 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*4 + r; 5777 remotePointsNew[m].rank = rrank; 5778 } 5779 for (r = 0; r < 1; ++r, ++m) { 5780 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart) + r; 5781 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 5782 remotePointsNew[m].rank = rrank; 5783 } 5784 } 5785 break; 5786 case 3: 5787 /* Hybrid simplicial 2D */ 5788 if ((p >= vStart) && (p < vEnd)) { 5789 /* Old vertices stay the same */ 5790 localPointsNew[m] = vStartNew + (p - vStart); 5791 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5792 remotePointsNew[m].rank = rrank; 5793 ++m; 5794 } else if ((p >= fStart) && (p < fMax)) { 5795 /* Old interior faces add new faces and vertex */ 5796 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5797 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5798 remotePointsNew[m].rank = rrank; 5799 ++m; 5800 for (r = 0; r < 2; ++r, ++m) { 5801 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5802 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5803 remotePointsNew[m].rank = rrank; 5804 } 5805 } else if ((p >= fMax) && (p < fEnd)) { 5806 /* Old hybrid faces stay the same */ 5807 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5808 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5809 remotePointsNew[m].rank = rrank; 5810 ++m; 5811 } else if ((p >= cStart) && (p < cMax)) { 5812 /* Old interior cells add new cells and interior faces */ 5813 for (r = 0; r < 4; ++r, ++m) { 5814 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5815 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5816 remotePointsNew[m].rank = rrank; 5817 } 5818 for (r = 0; r < 3; ++r, ++m) { 5819 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5820 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5821 remotePointsNew[m].rank = rrank; 5822 } 5823 } else if ((p >= cStart) && (p < cMax)) { 5824 /* Old hybrid cells add new cells and hybrid face */ 5825 for (r = 0; r < 2; ++r, ++m) { 5826 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5827 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5828 remotePointsNew[m].rank = rrank; 5829 } 5830 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5831 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]); 5832 remotePointsNew[m].rank = rrank; 5833 ++m; 5834 } 5835 break; 5836 case 4: 5837 /* Hybrid Hex 2D */ 5838 if ((p >= vStart) && (p < vEnd)) { 5839 /* Old vertices stay the same */ 5840 localPointsNew[m] = vStartNew + (p - vStart); 5841 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5842 remotePointsNew[m].rank = rrank; 5843 ++m; 5844 } else if ((p >= fStart) && (p < fMax)) { 5845 /* Old interior faces add new faces and vertex */ 5846 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5847 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5848 remotePointsNew[m].rank = rrank; 5849 ++m; 5850 for (r = 0; r < 2; ++r, ++m) { 5851 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5852 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5853 remotePointsNew[m].rank = rrank; 5854 } 5855 } else if ((p >= fMax) && (p < fEnd)) { 5856 /* Old hybrid faces stay the same */ 5857 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5858 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5859 remotePointsNew[m].rank = rrank; 5860 ++m; 5861 } else if ((p >= cStart) && (p < cMax)) { 5862 /* Old interior cells add new cells, interior faces, and vertex */ 5863 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 5864 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 5865 remotePointsNew[m].rank = rrank; 5866 ++m; 5867 for (r = 0; r < 4; ++r, ++m) { 5868 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5869 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5870 remotePointsNew[m].rank = rrank; 5871 } 5872 for (r = 0; r < 4; ++r, ++m) { 5873 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5874 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5875 remotePointsNew[m].rank = rrank; 5876 } 5877 } else if ((p >= cStart) && (p < cMax)) { 5878 /* Old hybrid cells add new cells and hybrid face */ 5879 for (r = 0; r < 2; ++r, ++m) { 5880 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5881 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5882 remotePointsNew[m].rank = rrank; 5883 } 5884 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5885 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]); 5886 remotePointsNew[m].rank = rrank; 5887 ++m; 5888 } 5889 break; 5890 case 5: 5891 /* Simplicial 3D */ 5892 if ((p >= vStart) && (p < vEnd)) { 5893 /* Old vertices stay the same */ 5894 localPointsNew[m] = vStartNew + (p - vStart); 5895 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5896 remotePointsNew[m].rank = rrank; 5897 ++m; 5898 } else if ((p >= eStart) && (p < eEnd)) { 5899 /* Old edges add new edges and vertex */ 5900 for (r = 0; r < 2; ++r, ++m) { 5901 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5902 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5903 remotePointsNew[m].rank = rrank; 5904 } 5905 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5906 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5907 remotePointsNew[m].rank = rrank; 5908 ++m; 5909 } else if ((p >= fStart) && (p < fEnd)) { 5910 /* Old faces add new faces and face edges */ 5911 for (r = 0; r < 4; ++r, ++m) { 5912 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5913 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5914 remotePointsNew[m].rank = rrank; 5915 } 5916 for (r = 0; r < 3; ++r, ++m) { 5917 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 5918 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*3 + r; 5919 remotePointsNew[m].rank = rrank; 5920 } 5921 } else if ((p >= cStart) && (p < cEnd)) { 5922 /* Old cells add new cells and interior faces and edges */ 5923 for (r = 0; r < 8; ++r, ++m) { 5924 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5925 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5926 remotePointsNew[m].rank = rrank; 5927 } 5928 for (r = 0; r < 8; ++r, ++m) { 5929 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 5930 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*8 + r; 5931 remotePointsNew[m].rank = rrank; 5932 } 5933 for (r = 0; r < 1; ++r, ++m) { 5934 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 5935 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*1 + r; 5936 remotePointsNew[m].rank = rrank; 5937 } 5938 } 5939 break; 5940 case 7: 5941 /* Hybrid Simplicial 3D */ 5942 if ((p >= vStart) && (p < vEnd)) { 5943 /* Interior vertices stay the same */ 5944 localPointsNew[m] = vStartNew + (p - vStart); 5945 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5946 remotePointsNew[m].rank = rrank; 5947 ++m; 5948 } else if ((p >= eStart) && (p < eMax)) { 5949 /* Interior edges add new edges and vertex */ 5950 for (r = 0; r < 2; ++r, ++m) { 5951 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5952 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5953 remotePointsNew[m].rank = rrank; 5954 } 5955 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5956 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5957 remotePointsNew[m].rank = rrank; 5958 ++m; 5959 } else if ((p >= eMax) && (p < eEnd)) { 5960 /* Hybrid edges stay the same */ 5961 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5962 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]); 5963 remotePointsNew[m].rank = rrank; 5964 ++m; 5965 } else if ((p >= fStart) && (p < fMax)) { 5966 /* Interior faces add new faces and edges */ 5967 for (r = 0; r < 4; ++r, ++m) { 5968 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5969 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5970 remotePointsNew[m].rank = rrank; 5971 } 5972 for (r = 0; r < 3; ++r, ++m) { 5973 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5974 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5975 remotePointsNew[m].rank = rrank; 5976 } 5977 } else if ((p >= fMax) && (p < fEnd)) { 5978 /* Hybrid faces add new faces and edges */ 5979 for (r = 0; r < 2; ++r, ++m) { 5980 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5981 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; 5982 remotePointsNew[m].rank = rrank; 5983 } 5984 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 5985 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n]) + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5986 remotePointsNew[m].rank = rrank; 5987 ++m; 5988 } else if ((p >= cStart) && (p < cMax)) { 5989 /* Interior cells add new cells, faces, and edges */ 5990 for (r = 0; r < 8; ++r, ++m) { 5991 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5992 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5993 remotePointsNew[m].rank = rrank; 5994 } 5995 for (r = 0; r < 8; ++r, ++m) { 5996 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5997 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 5998 remotePointsNew[m].rank = rrank; 5999 } 6000 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + r; 6001 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; 6002 remotePointsNew[m].rank = rrank; 6003 ++m; 6004 } else if ((p >= cMax) && (p < cEnd)) { 6005 /* Hybrid cells add new cells and faces */ 6006 for (r = 0; r < 4; ++r, ++m) { 6007 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6008 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6009 remotePointsNew[m].rank = rrank; 6010 } 6011 for (r = 0; r < 3; ++r, ++m) { 6012 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6013 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; 6014 remotePointsNew[m].rank = rrank; 6015 } 6016 } 6017 break; 6018 case 6: 6019 /* Hex 3D */ 6020 if ((p >= vStart) && (p < vEnd)) { 6021 /* Old vertices stay the same */ 6022 localPointsNew[m] = vStartNew + (p - vStart); 6023 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6024 remotePointsNew[m].rank = rrank; 6025 ++m; 6026 } else if ((p >= eStart) && (p < eEnd)) { 6027 /* Old edges add new edges and vertex */ 6028 for (r = 0; r < 2; ++r, ++m) { 6029 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6030 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6031 remotePointsNew[m].rank = rrank; 6032 } 6033 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6034 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6035 remotePointsNew[m].rank = rrank; 6036 ++m; 6037 } else if ((p >= fStart) && (p < fEnd)) { 6038 /* Old faces add new faces, edges, and vertex */ 6039 for (r = 0; r < 4; ++r, ++m) { 6040 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6041 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6042 remotePointsNew[m].rank = rrank; 6043 } 6044 for (r = 0; r < 4; ++r, ++m) { 6045 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6046 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + (rp - rfStart[n])*4 + r; 6047 remotePointsNew[m].rank = rrank; 6048 } 6049 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6050 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 6051 remotePointsNew[m].rank = rrank; 6052 ++m; 6053 } else if ((p >= cStart) && (p < cEnd)) { 6054 /* Old cells add new cells, faces, edges, and vertex */ 6055 for (r = 0; r < 8; ++r, ++m) { 6056 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6057 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6058 remotePointsNew[m].rank = rrank; 6059 } 6060 for (r = 0; r < 12; ++r, ++m) { 6061 localPointsNew[m] = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6062 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*12 + r; 6063 remotePointsNew[m].rank = rrank; 6064 } 6065 for (r = 0; r < 6; ++r, ++m) { 6066 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6067 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*4 + (rp - rcStart[n])*6 + r; 6068 remotePointsNew[m].rank = rrank; 6069 } 6070 for (r = 0; r < 1; ++r, ++m) { 6071 localPointsNew[m] = vStartNew + (eEnd - eStart) + (fEnd - fStart) + (p - cStart) + r; 6072 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]) + r; 6073 remotePointsNew[m].rank = rrank; 6074 } 6075 } 6076 break; 6077 case 8: 6078 /* Hybrid Hex 3D */ 6079 if ((p >= vStart) && (p < vEnd)) { 6080 /* Interior vertices stay the same */ 6081 localPointsNew[m] = vStartNew + (p - vStart); 6082 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6083 remotePointsNew[m].rank = rrank; 6084 ++m; 6085 } else if ((p >= eStart) && (p < eMax)) { 6086 /* Interior edges add new edges and vertex */ 6087 for (r = 0; r < 2; ++r, ++m) { 6088 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6089 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6090 remotePointsNew[m].rank = rrank; 6091 } 6092 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6093 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6094 remotePointsNew[m].rank = rrank; 6095 ++m; 6096 } else if ((p >= eMax) && (p < eEnd)) { 6097 /* Hybrid edges stay the same */ 6098 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6099 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+1]); 6100 remotePointsNew[m].rank = rrank; 6101 ++m; 6102 } else if ((p >= fStart) && (p < fMax)) { 6103 /* Interior faces add new faces, edges, and vertex */ 6104 for (r = 0; r < 4; ++r, ++m) { 6105 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6106 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6107 remotePointsNew[m].rank = rrank; 6108 } 6109 for (r = 0; r < 4; ++r, ++m) { 6110 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6111 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 6112 remotePointsNew[m].rank = rrank; 6113 } 6114 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6115 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 6116 remotePointsNew[m].rank = rrank; 6117 ++m; 6118 } else if ((p >= fMax) && (p < fEnd)) { 6119 /* Hybrid faces add new faces and edges */ 6120 for (r = 0; r < 2; ++r, ++m) { 6121 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6122 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; 6123 remotePointsNew[m].rank = rrank; 6124 } 6125 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax); 6126 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]); 6127 remotePointsNew[m].rank = rrank; 6128 ++m; 6129 } else if ((p >= cStart) && (p < cMax)) { 6130 /* Interior cells add new cells, faces, edges, and vertex */ 6131 for (r = 0; r < 8; ++r, ++m) { 6132 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6133 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6134 remotePointsNew[m].rank = rrank; 6135 } 6136 for (r = 0; r < 12; ++r, ++m) { 6137 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6138 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6139 remotePointsNew[m].rank = rrank; 6140 } 6141 for (r = 0; r < 6; ++r, ++m) { 6142 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6143 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; 6144 remotePointsNew[m].rank = rrank; 6145 } 6146 for (r = 0; r < 1; ++r, ++m) { 6147 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6148 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6149 remotePointsNew[m].rank = rrank; 6150 } 6151 } else if ((p >= cMax) && (p < cEnd)) { 6152 /* Hybrid cells add new cells, faces, and edges */ 6153 for (r = 0; r < 4; ++r, ++m) { 6154 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6155 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6156 remotePointsNew[m].rank = rrank; 6157 } 6158 for (r = 0; r < 4; ++r, ++m) { 6159 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6160 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6161 remotePointsNew[m].rank = rrank; 6162 } 6163 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6164 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]); 6165 remotePointsNew[m].rank = rrank; 6166 ++m; 6167 } 6168 break; 6169 default: 6170 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6171 } 6172 } 6173 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6174 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6175 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6176 { 6177 PetscSFNode *rp, *rtmp; 6178 PetscInt *lp, *idx, *ltmp, i; 6179 6180 /* SF needs sorted leaves to correct calculate Gather */ 6181 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 6182 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 6183 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 6184 for (i = 0; i < numLeavesNew; ++i) idx[i] = i; 6185 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 6186 for (i = 0; i < numLeavesNew; ++i) { 6187 lp[i] = localPointsNew[idx[i]]; 6188 rp[i] = remotePointsNew[idx[i]]; 6189 } 6190 ltmp = localPointsNew; 6191 localPointsNew = lp; 6192 rtmp = remotePointsNew; 6193 remotePointsNew = rp; 6194 ierr = PetscFree(idx);CHKERRQ(ierr); 6195 ierr = PetscFree(ltmp);CHKERRQ(ierr); 6196 ierr = PetscFree(rtmp);CHKERRQ(ierr); 6197 } 6198 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6199 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6200 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6201 PetscFunctionReturn(0); 6202 } 6203 6204 #undef __FUNCT__ 6205 #define __FUNCT__ "CellRefinerCreateLabels" 6206 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6207 { 6208 PetscInt numLabels, l; 6209 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6210 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6211 PetscErrorCode ierr; 6212 6213 PetscFunctionBegin; 6214 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6215 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6216 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6217 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6218 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6219 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6220 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6221 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6222 switch (refiner) { 6223 case 0: break; 6224 case 7: 6225 case 8: 6226 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6227 case 3: 6228 case 4: 6229 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6230 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6231 } 6232 for (l = 0; l < numLabels; ++l) { 6233 DMLabel label, labelNew; 6234 const char *lname; 6235 PetscBool isDepth; 6236 IS valueIS; 6237 const PetscInt *values; 6238 PetscInt numValues, val; 6239 6240 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6241 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6242 if (isDepth) continue; 6243 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6244 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6245 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6246 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6247 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6248 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6249 for (val = 0; val < numValues; ++val) { 6250 IS pointIS; 6251 const PetscInt *points; 6252 PetscInt numPoints, n; 6253 6254 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6255 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6256 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6257 for (n = 0; n < numPoints; ++n) { 6258 const PetscInt p = points[n]; 6259 switch (refiner) { 6260 case 1: 6261 /* Simplicial 2D */ 6262 if ((p >= vStart) && (p < vEnd)) { 6263 /* Old vertices stay the same */ 6264 newp = vStartNew + (p - vStart); 6265 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6266 } else if ((p >= fStart) && (p < fEnd)) { 6267 /* Old faces add new faces and vertex */ 6268 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6269 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6270 for (r = 0; r < 2; ++r) { 6271 newp = fStartNew + (p - fStart)*2 + r; 6272 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6273 } 6274 } else if ((p >= cStart) && (p < cEnd)) { 6275 /* Old cells add new cells and interior faces */ 6276 for (r = 0; r < 4; ++r) { 6277 newp = cStartNew + (p - cStart)*4 + r; 6278 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6279 } 6280 for (r = 0; r < 3; ++r) { 6281 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6282 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6283 } 6284 } 6285 break; 6286 case 2: 6287 /* Hex 2D */ 6288 if ((p >= vStart) && (p < vEnd)) { 6289 /* Old vertices stay the same */ 6290 newp = vStartNew + (p - vStart); 6291 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6292 } else if ((p >= fStart) && (p < fEnd)) { 6293 /* Old faces add new faces and vertex */ 6294 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6295 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6296 for (r = 0; r < 2; ++r) { 6297 newp = fStartNew + (p - fStart)*2 + r; 6298 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6299 } 6300 } else if ((p >= cStart) && (p < cEnd)) { 6301 /* Old cells add new cells and interior faces and vertex */ 6302 for (r = 0; r < 4; ++r) { 6303 newp = cStartNew + (p - cStart)*4 + r; 6304 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6305 } 6306 for (r = 0; r < 4; ++r) { 6307 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6308 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6309 } 6310 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6311 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6312 } 6313 break; 6314 case 3: 6315 /* Hybrid simplicial 2D */ 6316 if ((p >= vStart) && (p < vEnd)) { 6317 /* Old vertices stay the same */ 6318 newp = vStartNew + (p - vStart); 6319 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6320 } else if ((p >= fStart) && (p < fMax)) { 6321 /* Old interior faces add new faces and vertex */ 6322 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6323 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6324 for (r = 0; r < 2; ++r) { 6325 newp = fStartNew + (p - fStart)*2 + r; 6326 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6327 } 6328 } else if ((p >= fMax) && (p < fEnd)) { 6329 /* Old hybrid faces stay the same */ 6330 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6331 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6332 } else if ((p >= cStart) && (p < cMax)) { 6333 /* Old interior cells add new cells and interior faces */ 6334 for (r = 0; r < 4; ++r) { 6335 newp = cStartNew + (p - cStart)*4 + r; 6336 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6337 } 6338 for (r = 0; r < 3; ++r) { 6339 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6340 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6341 } 6342 } else if ((p >= cMax) && (p < cEnd)) { 6343 /* Old hybrid cells add new cells and hybrid face */ 6344 for (r = 0; r < 2; ++r) { 6345 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6346 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6347 } 6348 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6349 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6350 } 6351 break; 6352 case 4: 6353 /* Hybrid Hex 2D */ 6354 if ((p >= vStart) && (p < vEnd)) { 6355 /* Old vertices stay the same */ 6356 newp = vStartNew + (p - vStart); 6357 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6358 } else if ((p >= fStart) && (p < fMax)) { 6359 /* Old interior faces add new faces and vertex */ 6360 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6361 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6362 for (r = 0; r < 2; ++r) { 6363 newp = fStartNew + (p - fStart)*2 + r; 6364 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6365 } 6366 } else if ((p >= fMax) && (p < fEnd)) { 6367 /* Old hybrid faces stay the same */ 6368 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6369 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6370 } else if ((p >= cStart) && (p < cMax)) { 6371 /* Old interior cells add new cells, interior faces, and vertex */ 6372 for (r = 0; r < 4; ++r) { 6373 newp = cStartNew + (p - cStart)*4 + r; 6374 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6375 } 6376 for (r = 0; r < 4; ++r) { 6377 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6378 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6379 } 6380 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6381 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6382 } else if ((p >= cMax) && (p < cEnd)) { 6383 /* Old hybrid cells add new cells and hybrid face */ 6384 for (r = 0; r < 2; ++r) { 6385 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6386 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6387 } 6388 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6389 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6390 } 6391 break; 6392 case 5: 6393 /* Simplicial 3D */ 6394 if ((p >= vStart) && (p < vEnd)) { 6395 /* Old vertices stay the same */ 6396 newp = vStartNew + (p - vStart); 6397 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6398 } else if ((p >= eStart) && (p < eEnd)) { 6399 /* Old edges add new edges and vertex */ 6400 for (r = 0; r < 2; ++r) { 6401 newp = eStartNew + (p - eStart)*2 + r; 6402 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6403 } 6404 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6405 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6406 } else if ((p >= fStart) && (p < fEnd)) { 6407 /* Old faces add new faces and edges */ 6408 for (r = 0; r < 4; ++r) { 6409 newp = fStartNew + (p - fStart)*4 + r; 6410 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6411 } 6412 for (r = 0; r < 3; ++r) { 6413 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6414 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6415 } 6416 } else if ((p >= cStart) && (p < cEnd)) { 6417 /* Old cells add new cells and interior faces and edges */ 6418 for (r = 0; r < 8; ++r) { 6419 newp = cStartNew + (p - cStart)*8 + r; 6420 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6421 } 6422 for (r = 0; r < 8; ++r) { 6423 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6424 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6425 } 6426 for (r = 0; r < 1; ++r) { 6427 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6428 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6429 } 6430 } 6431 break; 6432 case 7: 6433 /* Hybrid Simplicial 3D */ 6434 if ((p >= vStart) && (p < vEnd)) { 6435 /* Interior vertices stay the same */ 6436 newp = vStartNew + (p - vStart); 6437 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6438 } else if ((p >= eStart) && (p < eMax)) { 6439 /* Interior edges add new edges and vertex */ 6440 for (r = 0; r < 2; ++r) { 6441 newp = eStartNew + (p - eStart)*2 + r; 6442 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6443 } 6444 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6445 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6446 } else if ((p >= eMax) && (p < eEnd)) { 6447 /* Hybrid edges stay the same */ 6448 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6449 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6450 } else if ((p >= fStart) && (p < fMax)) { 6451 /* Interior faces add new faces and edges */ 6452 for (r = 0; r < 4; ++r) { 6453 newp = fStartNew + (p - fStart)*4 + r; 6454 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6455 } 6456 for (r = 0; r < 3; ++r) { 6457 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6458 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6459 } 6460 } else if ((p >= fMax) && (p < fEnd)) { 6461 /* Hybrid faces add new faces and edges */ 6462 for (r = 0; r < 2; ++r) { 6463 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6464 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6465 } 6466 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6467 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6468 } else if ((p >= cStart) && (p < cMax)) { 6469 /* Interior cells add new cells, faces, and edges */ 6470 for (r = 0; r < 8; ++r) { 6471 newp = cStartNew + (p - cStart)*8 + r; 6472 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6473 } 6474 for (r = 0; r < 8; ++r) { 6475 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6476 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6477 } 6478 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6479 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6480 } else if ((p >= cMax) && (p < cEnd)) { 6481 /* Hybrid cells add new cells and faces */ 6482 for (r = 0; r < 4; ++r) { 6483 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6484 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6485 } 6486 for (r = 0; r < 3; ++r) { 6487 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6488 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6489 } 6490 } 6491 break; 6492 case 6: 6493 /* Hex 3D */ 6494 if ((p >= vStart) && (p < vEnd)) { 6495 /* Old vertices stay the same */ 6496 newp = vStartNew + (p - vStart); 6497 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6498 } else if ((p >= eStart) && (p < eEnd)) { 6499 /* Old edges add new edges and vertex */ 6500 for (r = 0; r < 2; ++r) { 6501 newp = eStartNew + (p - eStart)*2 + r; 6502 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6503 } 6504 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6505 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6506 } else if ((p >= fStart) && (p < fEnd)) { 6507 /* Old faces add new faces, edges, and vertex */ 6508 for (r = 0; r < 4; ++r) { 6509 newp = fStartNew + (p - fStart)*4 + r; 6510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6511 } 6512 for (r = 0; r < 4; ++r) { 6513 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6514 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6515 } 6516 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6517 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6518 } else if ((p >= cStart) && (p < cEnd)) { 6519 /* Old cells add new cells, faces, edges, and vertex */ 6520 for (r = 0; r < 8; ++r) { 6521 newp = cStartNew + (p - cStart)*8 + r; 6522 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6523 } 6524 for (r = 0; r < 12; ++r) { 6525 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6526 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6527 } 6528 for (r = 0; r < 6; ++r) { 6529 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6530 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6531 } 6532 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6533 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6534 } 6535 break; 6536 case 8: 6537 /* Hybrid Hex 3D */ 6538 if ((p >= vStart) && (p < vEnd)) { 6539 /* Interior vertices stay the same */ 6540 newp = vStartNew + (p - vStart); 6541 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6542 } else if ((p >= eStart) && (p < eMax)) { 6543 /* Interior edges add new edges and vertex */ 6544 for (r = 0; r < 2; ++r) { 6545 newp = eStartNew + (p - eStart)*2 + r; 6546 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6547 } 6548 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6549 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6550 } else if ((p >= eMax) && (p < eEnd)) { 6551 /* Hybrid edges stay the same */ 6552 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6553 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6554 } else if ((p >= fStart) && (p < fMax)) { 6555 /* Interior faces add new faces, edges, and vertex */ 6556 for (r = 0; r < 4; ++r) { 6557 newp = fStartNew + (p - fStart)*4 + r; 6558 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6559 } 6560 for (r = 0; r < 4; ++r) { 6561 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6562 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6563 } 6564 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6565 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6566 } else if ((p >= fMax) && (p < fEnd)) { 6567 /* Hybrid faces add new faces and edges */ 6568 for (r = 0; r < 2; ++r) { 6569 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6570 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6571 } 6572 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6573 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6574 } else if ((p >= cStart) && (p < cMax)) { 6575 /* Interior cells add new cells, faces, edges, and vertex */ 6576 for (r = 0; r < 8; ++r) { 6577 newp = cStartNew + (p - cStart)*8 + r; 6578 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6579 } 6580 for (r = 0; r < 12; ++r) { 6581 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6582 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6583 } 6584 for (r = 0; r < 6; ++r) { 6585 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6586 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6587 } 6588 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6589 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6590 } else if ((p >= cMax) && (p < cEnd)) { 6591 /* Hybrid cells add new cells, faces, and edges */ 6592 for (r = 0; r < 4; ++r) { 6593 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6594 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6595 } 6596 for (r = 0; r < 4; ++r) { 6597 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6598 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6599 } 6600 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6601 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6602 } 6603 break; 6604 default: 6605 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6606 } 6607 } 6608 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6609 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6610 } 6611 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6612 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6613 if (0) { 6614 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6615 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6616 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6617 } 6618 } 6619 PetscFunctionReturn(0); 6620 } 6621 6622 #undef __FUNCT__ 6623 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6624 /* This will only work for interpolated meshes */ 6625 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6626 { 6627 DM rdm; 6628 PetscInt *depthSize; 6629 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6630 PetscErrorCode ierr; 6631 6632 PetscFunctionBegin; 6633 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6634 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6635 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6636 ierr = DMPlexSetDimension(rdm, dim);CHKERRQ(ierr); 6637 /* Calculate number of new points of each depth */ 6638 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6639 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6640 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6641 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6642 /* Step 1: Set chart */ 6643 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6644 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6645 /* Step 2: Set cone/support sizes */ 6646 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6647 /* Step 3: Setup refined DM */ 6648 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6649 /* Step 4: Set cones and supports */ 6650 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6651 /* Step 5: Stratify */ 6652 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6653 /* Step 6: Set coordinates for vertices */ 6654 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6655 /* Step 7: Create pointSF */ 6656 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6657 /* Step 8: Create labels */ 6658 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6659 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6660 6661 *dmRefined = rdm; 6662 PetscFunctionReturn(0); 6663 } 6664 6665 #undef __FUNCT__ 6666 #define __FUNCT__ "DMPlexCreateCoarsePointIS" 6667 /*@ 6668 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 6669 6670 Input Parameter: 6671 . dm - The coarse DM 6672 6673 Output Parameter: 6674 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 6675 6676 Level: developer 6677 6678 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 6679 @*/ 6680 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 6681 { 6682 CellRefiner cellRefiner; 6683 PetscInt *depthSize, *fpoints; 6684 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6685 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 6686 PetscErrorCode ierr; 6687 6688 PetscFunctionBegin; 6689 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6690 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6691 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6692 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 6693 ierr = PetscMalloc1((depth+1), &depthSize);CHKERRQ(ierr); 6694 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6695 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6696 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 6697 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 6698 switch (cellRefiner) { 6699 case 1: /* Simplicial 2D */ 6700 case 3: /* Hybrid simplicial 2D */ 6701 case 2: /* Hex 2D */ 6702 case 4: /* Hybrid Hex 2D */ 6703 case 5: /* Simplicial 3D */ 6704 case 7: /* Hybrid Simplicial 3D */ 6705 case 6: /* Hex 3D */ 6706 case 8: /* Hybrid Hex 3D */ 6707 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 6708 break; 6709 default: 6710 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 6711 } 6712 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 6713 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6714 PetscFunctionReturn(0); 6715 } 6716 6717 #undef __FUNCT__ 6718 #define __FUNCT__ "DMPlexSetRefinementUniform" 6719 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6720 { 6721 DM_Plex *mesh = (DM_Plex*) dm->data; 6722 6723 PetscFunctionBegin; 6724 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6725 mesh->refinementUniform = refinementUniform; 6726 PetscFunctionReturn(0); 6727 } 6728 6729 #undef __FUNCT__ 6730 #define __FUNCT__ "DMPlexGetRefinementUniform" 6731 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6732 { 6733 DM_Plex *mesh = (DM_Plex*) dm->data; 6734 6735 PetscFunctionBegin; 6736 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6737 PetscValidPointer(refinementUniform, 2); 6738 *refinementUniform = mesh->refinementUniform; 6739 PetscFunctionReturn(0); 6740 } 6741 6742 #undef __FUNCT__ 6743 #define __FUNCT__ "DMPlexSetRefinementLimit" 6744 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6745 { 6746 DM_Plex *mesh = (DM_Plex*) dm->data; 6747 6748 PetscFunctionBegin; 6749 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6750 mesh->refinementLimit = refinementLimit; 6751 PetscFunctionReturn(0); 6752 } 6753 6754 #undef __FUNCT__ 6755 #define __FUNCT__ "DMPlexGetRefinementLimit" 6756 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6757 { 6758 DM_Plex *mesh = (DM_Plex*) dm->data; 6759 6760 PetscFunctionBegin; 6761 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6762 PetscValidPointer(refinementLimit, 2); 6763 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6764 *refinementLimit = mesh->refinementLimit; 6765 PetscFunctionReturn(0); 6766 } 6767 6768 #undef __FUNCT__ 6769 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6770 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6771 { 6772 PetscInt dim, cStart, cEnd, coneSize, cMax; 6773 PetscErrorCode ierr; 6774 6775 PetscFunctionBegin; 6776 ierr = DMPlexGetDimension(dm, &dim);CHKERRQ(ierr); 6777 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6778 if (cEnd <= cStart) {*cellRefiner = 0; PetscFunctionReturn(0);} 6779 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6780 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6781 switch (dim) { 6782 case 2: 6783 switch (coneSize) { 6784 case 3: 6785 if (cMax >= 0) *cellRefiner = 3; /* Hybrid */ 6786 else *cellRefiner = 1; /* Triangular */ 6787 break; 6788 case 4: 6789 if (cMax >= 0) *cellRefiner = 4; /* Hybrid */ 6790 else *cellRefiner = 2; /* Quadrilateral */ 6791 break; 6792 default: 6793 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6794 } 6795 break; 6796 case 3: 6797 switch (coneSize) { 6798 case 4: 6799 if (cMax >= 0) *cellRefiner = 7; /* Hybrid */ 6800 else *cellRefiner = 5; /* Tetrahedral */ 6801 break; 6802 case 6: 6803 if (cMax >= 0) *cellRefiner = 8; /* Hybrid */ 6804 else *cellRefiner = 6; /* hexahedral */ 6805 break; 6806 default: 6807 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6808 } 6809 break; 6810 default: 6811 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6812 } 6813 PetscFunctionReturn(0); 6814 } 6815