1 #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2 #include <petscsf.h> 3 4 PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 5 { 6 PetscFunctionBegin; 7 if (cStart) *cStart = 0; 8 if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth]; 9 if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 10 if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 11 PetscFunctionReturn(0); 12 } 13 14 PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 15 { 16 PetscFunctionBegin; 17 if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth]; 18 if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 19 if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 20 if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 21 PetscFunctionReturn(0); 22 } 23 24 /* Gets the affine map from the original cell to each subcell */ 25 PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 26 { 27 PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ; 28 PetscInt dim, s; 29 PetscErrorCode ierr; 30 31 PetscFunctionBegin; 32 switch (refiner) { 33 case REFINER_NOOP: break; 34 case REFINER_SIMPLEX_2D: 35 /* 36 2 37 |\ 38 | \ 39 | \ 40 | \ 41 | C \ 42 | \ 43 | \ 44 2---1---1 45 |\ D / \ 46 | 2 0 \ 47 |A \ / B \ 48 0---0-------1 49 */ 50 dim = 2; 51 if (numSubcells) *numSubcells = 4; 52 if (v0) { 53 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 54 /* A */ 55 v[0+0] = -1.0; v[0+1] = -1.0; 56 j[0+0] = 0.5; j[0+1] = 0.0; 57 j[0+2] = 0.0; j[0+3] = 0.5; 58 /* B */ 59 v[2+0] = 0.0; v[2+1] = -1.0; 60 j[4+0] = 0.5; j[4+1] = 0.0; 61 j[4+2] = 0.0; j[4+3] = 0.5; 62 /* C */ 63 v[4+0] = -1.0; v[4+1] = 0.0; 64 j[8+0] = 0.5; j[8+1] = 0.0; 65 j[8+2] = 0.0; j[8+3] = 0.5; 66 /* D */ 67 v[6+0] = 0.0; v[6+1] = -1.0; 68 j[12+0] = 0.0; j[12+1] = -0.5; 69 j[12+2] = 0.5; j[12+3] = 0.5; 70 for (s = 0; s < 4; ++s) { 71 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 72 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 73 } 74 } 75 break; 76 case REFINER_HEX_2D: 77 /* 78 3---------2---------2 79 | | | 80 | D 2 C | 81 | | | 82 3----3----0----1----1 83 | | | 84 | A 0 B | 85 | | | 86 0---------0---------1 87 */ 88 dim = 2; 89 if (numSubcells) *numSubcells = 4; 90 if (v0) { 91 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 92 /* A */ 93 v[0+0] = -1.0; v[0+1] = -1.0; 94 j[0+0] = 0.5; j[0+1] = 0.0; 95 j[0+2] = 0.0; j[0+3] = 0.5; 96 /* B */ 97 v[2+0] = 0.0; v[2+1] = -1.0; 98 j[4+0] = 0.5; j[4+1] = 0.0; 99 j[4+2] = 0.0; j[4+3] = 0.5; 100 /* C */ 101 v[4+0] = 0.0; v[4+1] = 0.0; 102 j[8+0] = 0.5; j[8+1] = 0.0; 103 j[8+2] = 0.0; j[8+3] = 0.5; 104 /* D */ 105 v[6+0] = -1.0; v[6+1] = 0.0; 106 j[12+0] = 0.5; j[12+1] = 0.0; 107 j[12+2] = 0.0; j[12+3] = 0.5; 108 for (s = 0; s < 4; ++s) { 109 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 110 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 111 } 112 } 113 break; 114 default: 115 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 116 } 117 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 118 PetscFunctionReturn(0); 119 } 120 121 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 122 { 123 PetscErrorCode ierr; 124 125 PetscFunctionBegin; 126 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 127 PetscFunctionReturn(0); 128 } 129 130 /* Should this be here or in the DualSpace somehow? */ 131 PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside) 132 { 133 PetscReal sum = 0.0; 134 PetscInt d; 135 136 PetscFunctionBegin; 137 *inside = PETSC_TRUE; 138 switch (refiner) { 139 case REFINER_NOOP: break; 140 case REFINER_SIMPLEX_2D: 141 for (d = 0; d < 2; ++d) { 142 if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 143 sum += point[d]; 144 } 145 if (sum > 0.0) {*inside = PETSC_FALSE; break;} 146 break; 147 case REFINER_HEX_2D: 148 for (d = 0; d < 2; ++d) if ((point[d] < -1.0) || (point[d] > 1.0)) {*inside = PETSC_FALSE; break;} 149 break; 150 default: 151 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 152 } 153 PetscFunctionReturn(0); 154 } 155 156 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 157 { 158 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 159 PetscErrorCode ierr; 160 161 PetscFunctionBegin; 162 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 163 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 164 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 165 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 166 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 167 switch (refiner) { 168 case REFINER_NOOP: 169 break; 170 case REFINER_SIMPLEX_1D: 171 depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */ 172 depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */ 173 break; 174 case REFINER_SIMPLEX_2D: 175 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 176 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 177 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 178 break; 179 case REFINER_HYBRID_SIMPLEX_2D: 180 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 181 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 182 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 183 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 */ 184 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 185 break; 186 case REFINER_HEX_2D: 187 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 188 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 189 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 190 break; 191 case REFINER_HYBRID_HEX_2D: 192 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 193 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 194 /* Quadrilateral */ 195 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 196 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 197 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 198 /* Segment Prisms */ 199 depthSize[0] += 0; /* No hybrid vertices */ 200 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 201 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 202 break; 203 case REFINER_SIMPLEX_3D: 204 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 205 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 */ 206 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 207 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 208 break; 209 case REFINER_HYBRID_SIMPLEX_3D: 210 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 211 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 212 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 213 /* Tetrahedra */ 214 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 215 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 */ 216 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 217 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 218 /* Triangular Prisms */ 219 depthSize[0] += 0; /* No hybrid vertices */ 220 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 221 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 222 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 223 break; 224 case REFINER_HEX_3D: 225 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 226 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 */ 227 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 228 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 229 break; 230 case REFINER_HYBRID_HEX_3D: 231 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 232 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 233 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 234 /* Hexahedra */ 235 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 236 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 */ 237 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 238 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 239 /* Quadrilateral Prisms */ 240 depthSize[0] += 0; /* No hybrid vertices */ 241 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 242 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 243 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 244 break; 245 default: 246 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 247 } 248 PetscFunctionReturn(0); 249 } 250 251 /* Return triangle edge for orientation o, if it is r for o == 0 */ 252 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 253 return (o < 0 ? 2-(o+r) : o+r)%3; 254 } 255 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 256 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 257 } 258 259 /* Return triangle subface for orientation o, if it is r for o == 0 */ 260 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 261 return (o < 0 ? 3-(o+r) : o+r)%3; 262 } 263 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 264 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 265 } 266 267 /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */ 268 PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) { 269 return (o < 0 ? 1-(o+r) : o+r)%3; 270 } 271 PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) { 272 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 273 } 274 275 276 /* Return quad edge for orientation o, if it is r for o == 0 */ 277 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 278 return (o < 0 ? 3-(o+r) : o+r)%4; 279 } 280 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 281 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 282 } 283 284 /* Return quad subface for orientation o, if it is r for o == 0 */ 285 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 286 return (o < 0 ? 4-(o+r) : o+r)%4; 287 } 288 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 289 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 290 } 291 292 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 293 { 294 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 295 PetscErrorCode ierr; 296 297 PetscFunctionBegin; 298 if (!refiner) PetscFunctionReturn(0); 299 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 300 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 301 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 302 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 303 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 304 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 305 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 306 switch (refiner) { 307 case REFINER_SIMPLEX_1D: 308 /* All cells have 2 vertices */ 309 for (c = cStart; c < cEnd; ++c) { 310 for (r = 0; r < 2; ++r) { 311 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 312 313 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 314 } 315 } 316 /* Old vertices have identical supports */ 317 for (v = vStart; v < vEnd; ++v) { 318 const PetscInt newp = vStartNew + (v - vStart); 319 PetscInt size; 320 321 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 322 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 323 } 324 /* Cell vertices have support 2 */ 325 for (c = cStart; c < cEnd; ++c) { 326 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 327 328 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 329 } 330 break; 331 case REFINER_SIMPLEX_2D: 332 /* All cells have 3 faces */ 333 for (c = cStart; c < cEnd; ++c) { 334 for (r = 0; r < 4; ++r) { 335 const PetscInt newp = (c - cStart)*4 + r; 336 337 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 338 } 339 } 340 /* Split faces have 2 vertices and the same cells as the parent */ 341 for (f = fStart; f < fEnd; ++f) { 342 for (r = 0; r < 2; ++r) { 343 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 344 PetscInt size; 345 346 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 347 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 348 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 349 } 350 } 351 /* Interior faces have 2 vertices and 2 cells */ 352 for (c = cStart; c < cEnd; ++c) { 353 for (r = 0; r < 3; ++r) { 354 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 355 356 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 357 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 358 } 359 } 360 /* Old vertices have identical supports */ 361 for (v = vStart; v < vEnd; ++v) { 362 const PetscInt newp = vStartNew + (v - vStart); 363 PetscInt size; 364 365 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 366 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 367 } 368 /* Face vertices have 2 + cells*2 supports */ 369 for (f = fStart; f < fEnd; ++f) { 370 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 371 PetscInt size; 372 373 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 374 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 375 } 376 break; 377 case REFINER_HEX_2D: 378 /* All cells have 4 faces */ 379 for (c = cStart; c < cEnd; ++c) { 380 for (r = 0; r < 4; ++r) { 381 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 382 383 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 384 } 385 } 386 /* Split faces have 2 vertices and the same cells as the parent */ 387 for (f = fStart; f < fEnd; ++f) { 388 for (r = 0; r < 2; ++r) { 389 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 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 } 397 /* Interior faces have 2 vertices and 2 cells */ 398 for (c = cStart; c < cEnd; ++c) { 399 for (r = 0; r < 4; ++r) { 400 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 401 402 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 403 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 404 } 405 } 406 /* Old vertices have identical supports */ 407 for (v = vStart; v < vEnd; ++v) { 408 const PetscInt newp = vStartNew + (v - vStart); 409 PetscInt size; 410 411 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 412 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 413 } 414 /* Face vertices have 2 + cells supports */ 415 for (f = fStart; f < fEnd; ++f) { 416 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 417 PetscInt size; 418 419 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 420 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 421 } 422 /* Cell vertices have 4 supports */ 423 for (c = cStart; c < cEnd; ++c) { 424 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 425 426 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 427 } 428 break; 429 case REFINER_HYBRID_SIMPLEX_2D: 430 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 431 cMax = PetscMin(cEnd, cMax); 432 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 433 fMax = PetscMin(fEnd, fMax); 434 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 435 /* Interior cells have 3 faces */ 436 for (c = cStart; c < cMax; ++c) { 437 for (r = 0; r < 4; ++r) { 438 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 439 440 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 441 } 442 } 443 /* Hybrid cells have 4 faces */ 444 for (c = cMax; c < cEnd; ++c) { 445 for (r = 0; r < 2; ++r) { 446 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 447 448 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 449 } 450 } 451 /* Interior split faces have 2 vertices and the same cells as the parent */ 452 for (f = fStart; f < fMax; ++f) { 453 for (r = 0; r < 2; ++r) { 454 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 455 PetscInt size; 456 457 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 458 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 459 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 460 } 461 } 462 /* Interior cell faces have 2 vertices and 2 cells */ 463 for (c = cStart; c < cMax; ++c) { 464 for (r = 0; r < 3; ++r) { 465 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 466 467 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 468 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 469 } 470 } 471 /* Hybrid faces have 2 vertices and the same cells */ 472 for (f = fMax; f < fEnd; ++f) { 473 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 474 PetscInt size; 475 476 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 477 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 478 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 479 } 480 /* Hybrid cell faces have 2 vertices and 2 cells */ 481 for (c = cMax; c < cEnd; ++c) { 482 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 483 484 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 485 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 486 } 487 /* Old vertices have identical supports */ 488 for (v = vStart; v < vEnd; ++v) { 489 const PetscInt newp = vStartNew + (v - vStart); 490 PetscInt size; 491 492 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 493 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 494 } 495 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 496 for (f = fStart; f < fMax; ++f) { 497 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 498 const PetscInt *support; 499 PetscInt size, newSize = 2, s; 500 501 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 502 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 503 for (s = 0; s < size; ++s) { 504 if (support[s] >= cMax) newSize += 1; 505 else newSize += 2; 506 } 507 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 508 } 509 break; 510 case REFINER_HYBRID_HEX_2D: 511 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 512 cMax = PetscMin(cEnd, cMax); 513 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 514 fMax = PetscMin(fEnd, fMax); 515 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 516 /* Interior cells have 4 faces */ 517 for (c = cStart; c < cMax; ++c) { 518 for (r = 0; r < 4; ++r) { 519 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 520 521 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 522 } 523 } 524 /* Hybrid cells have 4 faces */ 525 for (c = cMax; c < cEnd; ++c) { 526 for (r = 0; r < 2; ++r) { 527 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 528 529 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 530 } 531 } 532 /* Interior split faces have 2 vertices and the same cells as the parent */ 533 for (f = fStart; f < fMax; ++f) { 534 for (r = 0; r < 2; ++r) { 535 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 536 PetscInt size; 537 538 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 539 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 540 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 541 } 542 } 543 /* Interior cell faces have 2 vertices and 2 cells */ 544 for (c = cStart; c < cMax; ++c) { 545 for (r = 0; r < 4; ++r) { 546 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 547 548 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 549 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 550 } 551 } 552 /* Hybrid faces have 2 vertices and the same cells */ 553 for (f = fMax; f < fEnd; ++f) { 554 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 555 PetscInt size; 556 557 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 558 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 559 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 560 } 561 /* Hybrid cell faces have 2 vertices and 2 cells */ 562 for (c = cMax; c < cEnd; ++c) { 563 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 564 565 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 566 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 567 } 568 /* Old vertices have identical supports */ 569 for (v = vStart; v < vEnd; ++v) { 570 const PetscInt newp = vStartNew + (v - vStart); 571 PetscInt size; 572 573 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 574 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 575 } 576 /* Face vertices have 2 + cells supports */ 577 for (f = fStart; f < fMax; ++f) { 578 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 579 PetscInt size; 580 581 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 582 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 583 } 584 /* Cell vertices have 4 supports */ 585 for (c = cStart; c < cMax; ++c) { 586 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 587 588 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 589 } 590 break; 591 case REFINER_SIMPLEX_3D: 592 /* All cells have 4 faces */ 593 for (c = cStart; c < cEnd; ++c) { 594 for (r = 0; r < 8; ++r) { 595 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 596 597 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 598 } 599 } 600 /* Split faces have 3 edges and the same cells as the parent */ 601 for (f = fStart; f < fEnd; ++f) { 602 for (r = 0; r < 4; ++r) { 603 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 604 PetscInt size; 605 606 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 607 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 608 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 609 } 610 } 611 /* Interior cell faces have 3 edges and 2 cells */ 612 for (c = cStart; c < cEnd; ++c) { 613 for (r = 0; r < 8; ++r) { 614 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 615 616 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 617 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 618 } 619 } 620 /* Split edges have 2 vertices and the same faces */ 621 for (e = eStart; e < eEnd; ++e) { 622 for (r = 0; r < 2; ++r) { 623 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 624 PetscInt size; 625 626 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 627 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 628 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 629 } 630 } 631 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 632 for (f = fStart; f < fEnd; ++f) { 633 for (r = 0; r < 3; ++r) { 634 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 635 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 636 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 637 638 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 639 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 640 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 641 for (s = 0; s < supportSize; ++s) { 642 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 643 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 644 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 645 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 646 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 647 er = GetTetSomethingInverse_Static(ornt[c], r); 648 if (er == eint[c]) { 649 intFaces += 1; 650 } else { 651 intFaces += 2; 652 } 653 } 654 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 655 } 656 } 657 /* Interior cell edges have 2 vertices and 4 faces */ 658 for (c = cStart; c < cEnd; ++c) { 659 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 660 661 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 662 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 663 } 664 /* Old vertices have identical supports */ 665 for (v = vStart; v < vEnd; ++v) { 666 const PetscInt newp = vStartNew + (v - vStart); 667 PetscInt size; 668 669 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 670 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 671 } 672 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 673 for (e = eStart; e < eEnd; ++e) { 674 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 675 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 676 677 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 678 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 679 for (s = 0; s < starSize*2; s += 2) { 680 const PetscInt *cone, *ornt; 681 PetscInt e01, e23; 682 683 if ((star[s] >= cStart) && (star[s] < cEnd)) { 684 /* Check edge 0-1 */ 685 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 686 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 687 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 688 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 689 /* Check edge 2-3 */ 690 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 691 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 692 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 693 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 694 if ((e01 == e) || (e23 == e)) ++cellSize; 695 } 696 } 697 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 698 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 699 } 700 break; 701 case REFINER_HYBRID_SIMPLEX_3D: 702 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 703 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 704 /* Interior cells have 4 faces */ 705 for (c = cStart; c < cMax; ++c) { 706 for (r = 0; r < 8; ++r) { 707 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 708 709 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 710 } 711 } 712 /* Hybrid cells have 5 faces */ 713 for (c = cMax; c < cEnd; ++c) { 714 for (r = 0; r < 4; ++r) { 715 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 716 717 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 718 } 719 } 720 /* Interior split faces have 3 edges and the same cells as the parent */ 721 for (f = fStart; f < fMax; ++f) { 722 for (r = 0; r < 4; ++r) { 723 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 724 PetscInt size; 725 726 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 727 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 728 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 729 } 730 } 731 /* Interior cell faces have 3 edges and 2 cells */ 732 for (c = cStart; c < cMax; ++c) { 733 for (r = 0; r < 8; ++r) { 734 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 735 736 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 737 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 738 } 739 } 740 /* Hybrid split faces have 4 edges and the same cells as the parent */ 741 for (f = fMax; f < fEnd; ++f) { 742 for (r = 0; r < 2; ++r) { 743 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 744 PetscInt size; 745 746 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 747 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 748 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 749 } 750 } 751 /* Hybrid cells faces have 4 edges and 2 cells */ 752 for (c = cMax; c < cEnd; ++c) { 753 for (r = 0; r < 3; ++r) { 754 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 755 756 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 757 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 758 } 759 } 760 /* Interior split edges have 2 vertices and the same faces */ 761 for (e = eStart; e < eMax; ++e) { 762 for (r = 0; r < 2; ++r) { 763 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 764 PetscInt size; 765 766 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 767 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 768 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 769 } 770 } 771 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 772 for (f = fStart; f < fMax; ++f) { 773 for (r = 0; r < 3; ++r) { 774 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 775 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 776 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 777 778 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 779 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 780 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 781 for (s = 0; s < supportSize; ++s) { 782 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 783 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 784 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 785 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 786 if (support[s] < cMax) { 787 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 788 er = GetTetSomethingInverse_Static(ornt[c], r); 789 if (er == eint[c]) { 790 intFaces += 1; 791 } else { 792 intFaces += 2; 793 } 794 } else { 795 intFaces += 1; 796 } 797 } 798 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 799 } 800 } 801 /* Interior cell edges have 2 vertices and 4 faces */ 802 for (c = cStart; c < cMax; ++c) { 803 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 804 805 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 806 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 807 } 808 /* Hybrid edges have 2 vertices and the same faces */ 809 for (e = eMax; e < eEnd; ++e) { 810 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 811 PetscInt size; 812 813 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 814 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 815 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 816 } 817 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 818 for (f = fMax; f < fEnd; ++f) { 819 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 820 PetscInt size; 821 822 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 823 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 824 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 825 } 826 /* Interior vertices have identical supports */ 827 for (v = vStart; v < vEnd; ++v) { 828 const PetscInt newp = vStartNew + (v - vStart); 829 PetscInt size; 830 831 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 832 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 833 } 834 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 835 for (e = eStart; e < eMax; ++e) { 836 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 837 const PetscInt *support; 838 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 839 840 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 841 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 842 for (s = 0; s < size; ++s) { 843 if (support[s] < fMax) faceSize += 2; 844 else faceSize += 1; 845 } 846 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 847 for (s = 0; s < starSize*2; s += 2) { 848 const PetscInt *cone, *ornt; 849 PetscInt e01, e23; 850 851 if ((star[s] >= cStart) && (star[s] < cMax)) { 852 /* Check edge 0-1 */ 853 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 854 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 855 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 856 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 857 /* Check edge 2-3 */ 858 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 859 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 860 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 861 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 862 if ((e01 == e) || (e23 == e)) ++cellSize; 863 } 864 } 865 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 866 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 867 } 868 break; 869 case REFINER_HEX_3D: 870 /* All cells have 6 faces */ 871 for (c = cStart; c < cEnd; ++c) { 872 for (r = 0; r < 8; ++r) { 873 const PetscInt newp = (c - cStart)*8 + r; 874 875 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 876 } 877 } 878 /* Split faces have 4 edges and the same cells as the parent */ 879 for (f = fStart; f < fEnd; ++f) { 880 for (r = 0; r < 4; ++r) { 881 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 882 PetscInt size; 883 884 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 885 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 886 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 887 } 888 } 889 /* Interior faces have 4 edges and 2 cells */ 890 for (c = cStart; c < cEnd; ++c) { 891 for (r = 0; r < 12; ++r) { 892 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 893 894 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 895 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 896 } 897 } 898 /* Split edges have 2 vertices and the same faces as the parent */ 899 for (e = eStart; e < eEnd; ++e) { 900 for (r = 0; r < 2; ++r) { 901 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 902 PetscInt size; 903 904 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 905 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 906 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 907 } 908 } 909 /* Face edges have 2 vertices and 2+cells faces */ 910 for (f = fStart; f < fEnd; ++f) { 911 for (r = 0; r < 4; ++r) { 912 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 913 PetscInt size; 914 915 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 916 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 917 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 918 } 919 } 920 /* Cell edges have 2 vertices and 4 faces */ 921 for (c = cStart; c < cEnd; ++c) { 922 for (r = 0; r < 6; ++r) { 923 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 924 925 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 926 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 927 } 928 } 929 /* Old vertices have identical supports */ 930 for (v = vStart; v < vEnd; ++v) { 931 const PetscInt newp = vStartNew + (v - vStart); 932 PetscInt size; 933 934 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 935 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 936 } 937 /* Edge vertices have 2 + faces supports */ 938 for (e = eStart; e < eEnd; ++e) { 939 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 940 PetscInt size; 941 942 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 943 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 944 } 945 /* Face vertices have 4 + cells supports */ 946 for (f = fStart; f < fEnd; ++f) { 947 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 948 PetscInt size; 949 950 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 951 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 952 } 953 /* Cell vertices have 6 supports */ 954 for (c = cStart; c < cEnd; ++c) { 955 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 956 957 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 958 } 959 break; 960 case REFINER_HYBRID_HEX_3D: 961 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 962 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 963 /* Interior cells have 6 faces */ 964 for (c = cStart; c < cMax; ++c) { 965 for (r = 0; r < 8; ++r) { 966 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 967 968 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 969 } 970 } 971 /* Hybrid cells have 6 faces */ 972 for (c = cMax; c < cEnd; ++c) { 973 for (r = 0; r < 4; ++r) { 974 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 975 976 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 977 } 978 } 979 /* Interior split faces have 4 edges and the same cells as the parent */ 980 for (f = fStart; f < fMax; ++f) { 981 for (r = 0; r < 4; ++r) { 982 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 983 PetscInt size; 984 985 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 986 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 987 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 988 } 989 } 990 /* Interior cell faces have 4 edges and 2 cells */ 991 for (c = cStart; c < cMax; ++c) { 992 for (r = 0; r < 12; ++r) { 993 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 994 995 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 996 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 997 } 998 } 999 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1000 for (f = fMax; f < fEnd; ++f) { 1001 for (r = 0; r < 2; ++r) { 1002 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1003 PetscInt size; 1004 1005 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1006 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1007 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1008 } 1009 } 1010 /* Hybrid cells faces have 4 edges and 2 cells */ 1011 for (c = cMax; c < cEnd; ++c) { 1012 for (r = 0; r < 4; ++r) { 1013 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1014 1015 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1016 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1017 } 1018 } 1019 /* Interior split edges have 2 vertices and the same faces as the parent */ 1020 for (e = eStart; e < eMax; ++e) { 1021 for (r = 0; r < 2; ++r) { 1022 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1023 PetscInt size; 1024 1025 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1026 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1027 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1028 } 1029 } 1030 /* Interior face edges have 2 vertices and 2+cells faces */ 1031 for (f = fStart; f < fMax; ++f) { 1032 for (r = 0; r < 4; ++r) { 1033 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1034 PetscInt size; 1035 1036 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1037 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1038 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1039 } 1040 } 1041 /* Interior cell edges have 2 vertices and 4 faces */ 1042 for (c = cStart; c < cMax; ++c) { 1043 for (r = 0; r < 6; ++r) { 1044 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1045 1046 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1047 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1048 } 1049 } 1050 /* Hybrid edges have 2 vertices and the same faces */ 1051 for (e = eMax; e < eEnd; ++e) { 1052 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1053 PetscInt size; 1054 1055 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1056 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1057 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1058 } 1059 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1060 for (f = fMax; f < fEnd; ++f) { 1061 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1062 PetscInt size; 1063 1064 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1065 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1066 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1067 } 1068 /* Hybrid cell edges have 2 vertices and 4 faces */ 1069 for (c = cMax; c < cEnd; ++c) { 1070 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1071 1072 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1073 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1074 } 1075 /* Interior vertices have identical supports */ 1076 for (v = vStart; v < vEnd; ++v) { 1077 const PetscInt newp = vStartNew + (v - vStart); 1078 PetscInt size; 1079 1080 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1081 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1082 } 1083 /* Interior edge vertices have 2 + faces supports */ 1084 for (e = eStart; e < eMax; ++e) { 1085 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1086 PetscInt size; 1087 1088 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1089 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1090 } 1091 /* Interior face vertices have 4 + cells supports */ 1092 for (f = fStart; f < fMax; ++f) { 1093 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1094 PetscInt size; 1095 1096 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1097 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1098 } 1099 /* Interior cell vertices have 6 supports */ 1100 for (c = cStart; c < cMax; ++c) { 1101 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1102 1103 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1104 } 1105 break; 1106 default: 1107 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1108 } 1109 PetscFunctionReturn(0); 1110 } 1111 1112 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1113 { 1114 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1115 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1116 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1117 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 1118 PetscErrorCode ierr; 1119 1120 PetscFunctionBegin; 1121 if (!refiner) PetscFunctionReturn(0); 1122 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1123 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1124 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1125 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1126 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1127 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1128 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1129 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1130 switch (refiner) { 1131 case REFINER_SIMPLEX_1D: 1132 /* Max support size of refined mesh is 2 */ 1133 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1134 /* All cells have 2 vertices */ 1135 for (c = cStart; c < cEnd; ++c) { 1136 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1137 1138 for (r = 0; r < 2; ++r) { 1139 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1140 const PetscInt *cone; 1141 PetscInt coneNew[2]; 1142 1143 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1144 coneNew[0] = vStartNew + (cone[0] - vStart); 1145 coneNew[1] = vStartNew + (cone[1] - vStart); 1146 coneNew[(r+1)%2] = newv; 1147 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1148 #if 1 1149 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew); 1150 for (p = 0; p < 2; ++p) { 1151 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); 1152 } 1153 #endif 1154 } 1155 } 1156 /* Old vertices have identical supports */ 1157 for (v = vStart; v < vEnd; ++v) { 1158 const PetscInt newp = vStartNew + (v - vStart); 1159 const PetscInt *support, *cone; 1160 PetscInt size, s; 1161 1162 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1163 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1164 for (s = 0; s < size; ++s) { 1165 PetscInt r = 0; 1166 1167 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1168 if (cone[1] == v) r = 1; 1169 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1170 } 1171 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1172 #if 1 1173 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1174 for (p = 0; p < size; ++p) { 1175 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); 1176 } 1177 #endif 1178 } 1179 /* Cell vertices have support of 2 cells */ 1180 for (c = cStart; c < cEnd; ++c) { 1181 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1182 1183 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1184 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1185 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1186 #if 1 1187 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1188 for (p = 0; p < 2; ++p) { 1189 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); 1190 } 1191 #endif 1192 } 1193 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1194 break; 1195 case REFINER_SIMPLEX_2D: 1196 /* 1197 2 1198 |\ 1199 | \ 1200 | \ 1201 | \ 1202 | C \ 1203 | \ 1204 | \ 1205 2---1---1 1206 |\ D / \ 1207 | 2 0 \ 1208 |A \ / B \ 1209 0---0-------1 1210 */ 1211 /* All cells have 3 faces */ 1212 for (c = cStart; c < cEnd; ++c) { 1213 const PetscInt newp = cStartNew + (c - cStart)*4; 1214 const PetscInt *cone, *ornt; 1215 PetscInt coneNew[3], orntNew[3]; 1216 1217 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1218 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1219 /* A triangle */ 1220 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1221 orntNew[0] = ornt[0]; 1222 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1223 orntNew[1] = -2; 1224 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1225 orntNew[2] = ornt[2]; 1226 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1227 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1228 #if 1 1229 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); 1230 for (p = 0; p < 3; ++p) { 1231 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); 1232 } 1233 #endif 1234 /* B triangle */ 1235 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1236 orntNew[0] = ornt[0]; 1237 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1238 orntNew[1] = ornt[1]; 1239 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1240 orntNew[2] = -2; 1241 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1242 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1243 #if 1 1244 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); 1245 for (p = 0; p < 3; ++p) { 1246 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); 1247 } 1248 #endif 1249 /* C triangle */ 1250 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1251 orntNew[0] = -2; 1252 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1253 orntNew[1] = ornt[1]; 1254 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1255 orntNew[2] = ornt[2]; 1256 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1257 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1258 #if 1 1259 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); 1260 for (p = 0; p < 3; ++p) { 1261 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); 1262 } 1263 #endif 1264 /* D triangle */ 1265 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1266 orntNew[0] = 0; 1267 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1268 orntNew[1] = 0; 1269 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1270 orntNew[2] = 0; 1271 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1272 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1273 #if 1 1274 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); 1275 for (p = 0; p < 3; ++p) { 1276 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); 1277 } 1278 #endif 1279 } 1280 /* Split faces have 2 vertices and the same cells as the parent */ 1281 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1282 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1283 for (f = fStart; f < fEnd; ++f) { 1284 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1285 1286 for (r = 0; r < 2; ++r) { 1287 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1288 const PetscInt *cone, *ornt, *support; 1289 PetscInt coneNew[2], coneSize, c, supportSize, s; 1290 1291 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1292 coneNew[0] = vStartNew + (cone[0] - vStart); 1293 coneNew[1] = vStartNew + (cone[1] - vStart); 1294 coneNew[(r+1)%2] = newv; 1295 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1296 #if 1 1297 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1298 for (p = 0; p < 2; ++p) { 1299 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); 1300 } 1301 #endif 1302 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1303 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1304 for (s = 0; s < supportSize; ++s) { 1305 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1306 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1307 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1308 for (c = 0; c < coneSize; ++c) { 1309 if (cone[c] == f) break; 1310 } 1311 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1312 } 1313 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1314 #if 1 1315 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1316 for (p = 0; p < supportSize; ++p) { 1317 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); 1318 } 1319 #endif 1320 } 1321 } 1322 /* Interior faces have 2 vertices and 2 cells */ 1323 for (c = cStart; c < cEnd; ++c) { 1324 const PetscInt *cone; 1325 1326 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1327 for (r = 0; r < 3; ++r) { 1328 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1329 PetscInt coneNew[2]; 1330 PetscInt supportNew[2]; 1331 1332 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1333 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1334 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1335 #if 1 1336 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1337 for (p = 0; p < 2; ++p) { 1338 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); 1339 } 1340 #endif 1341 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1342 supportNew[1] = (c - cStart)*4 + 3; 1343 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1344 #if 1 1345 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1346 for (p = 0; p < 2; ++p) { 1347 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); 1348 } 1349 #endif 1350 } 1351 } 1352 /* Old vertices have identical supports */ 1353 for (v = vStart; v < vEnd; ++v) { 1354 const PetscInt newp = vStartNew + (v - vStart); 1355 const PetscInt *support, *cone; 1356 PetscInt size, s; 1357 1358 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1359 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1360 for (s = 0; s < size; ++s) { 1361 PetscInt r = 0; 1362 1363 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1364 if (cone[1] == v) r = 1; 1365 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1366 } 1367 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1368 #if 1 1369 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1370 for (p = 0; p < size; ++p) { 1371 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); 1372 } 1373 #endif 1374 } 1375 /* Face vertices have 2 + cells*2 supports */ 1376 for (f = fStart; f < fEnd; ++f) { 1377 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1378 const PetscInt *cone, *support; 1379 PetscInt size, s; 1380 1381 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1382 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1383 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1384 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1385 for (s = 0; s < size; ++s) { 1386 PetscInt r = 0; 1387 1388 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1389 if (cone[1] == f) r = 1; 1390 else if (cone[2] == f) r = 2; 1391 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1392 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1393 } 1394 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1395 #if 1 1396 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1397 for (p = 0; p < 2+size*2; ++p) { 1398 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); 1399 } 1400 #endif 1401 } 1402 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1403 break; 1404 case REFINER_HEX_2D: 1405 /* 1406 3---------2---------2 1407 | | | 1408 | D 2 C | 1409 | | | 1410 3----3----0----1----1 1411 | | | 1412 | A 0 B | 1413 | | | 1414 0---------0---------1 1415 */ 1416 /* All cells have 4 faces */ 1417 for (c = cStart; c < cEnd; ++c) { 1418 const PetscInt newp = (c - cStart)*4; 1419 const PetscInt *cone, *ornt; 1420 PetscInt coneNew[4], orntNew[4]; 1421 1422 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1423 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1424 /* A quad */ 1425 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1426 orntNew[0] = ornt[0]; 1427 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1428 orntNew[1] = 0; 1429 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1430 orntNew[2] = -2; 1431 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1432 orntNew[3] = ornt[3]; 1433 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1434 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1435 #if 1 1436 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); 1437 for (p = 0; p < 4; ++p) { 1438 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); 1439 } 1440 #endif 1441 /* B quad */ 1442 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1443 orntNew[0] = ornt[0]; 1444 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1445 orntNew[1] = ornt[1]; 1446 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1447 orntNew[2] = 0; 1448 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1449 orntNew[3] = -2; 1450 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1451 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1452 #if 1 1453 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); 1454 for (p = 0; p < 4; ++p) { 1455 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); 1456 } 1457 #endif 1458 /* C quad */ 1459 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1460 orntNew[0] = -2; 1461 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1462 orntNew[1] = ornt[1]; 1463 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1464 orntNew[2] = ornt[2]; 1465 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1466 orntNew[3] = 0; 1467 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1468 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1469 #if 1 1470 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); 1471 for (p = 0; p < 4; ++p) { 1472 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); 1473 } 1474 #endif 1475 /* D quad */ 1476 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1477 orntNew[0] = 0; 1478 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1479 orntNew[1] = -2; 1480 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1481 orntNew[2] = ornt[2]; 1482 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1483 orntNew[3] = ornt[3]; 1484 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1485 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1486 #if 1 1487 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); 1488 for (p = 0; p < 4; ++p) { 1489 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); 1490 } 1491 #endif 1492 } 1493 /* Split faces have 2 vertices and the same cells as the parent */ 1494 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1495 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1496 for (f = fStart; f < fEnd; ++f) { 1497 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1498 1499 for (r = 0; r < 2; ++r) { 1500 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1501 const PetscInt *cone, *ornt, *support; 1502 PetscInt coneNew[2], coneSize, c, supportSize, s; 1503 1504 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1505 coneNew[0] = vStartNew + (cone[0] - vStart); 1506 coneNew[1] = vStartNew + (cone[1] - vStart); 1507 coneNew[(r+1)%2] = newv; 1508 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1509 #if 1 1510 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1511 for (p = 0; p < 2; ++p) { 1512 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); 1513 } 1514 #endif 1515 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1516 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1517 for (s = 0; s < supportSize; ++s) { 1518 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1519 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1520 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1521 for (c = 0; c < coneSize; ++c) { 1522 if (cone[c] == f) break; 1523 } 1524 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1525 } 1526 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1527 #if 1 1528 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1529 for (p = 0; p < supportSize; ++p) { 1530 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); 1531 } 1532 #endif 1533 } 1534 } 1535 /* Interior faces have 2 vertices and 2 cells */ 1536 for (c = cStart; c < cEnd; ++c) { 1537 const PetscInt *cone; 1538 PetscInt coneNew[2], supportNew[2]; 1539 1540 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1541 for (r = 0; r < 4; ++r) { 1542 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1543 1544 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1545 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1546 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1547 #if 1 1548 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1549 for (p = 0; p < 2; ++p) { 1550 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); 1551 } 1552 #endif 1553 supportNew[0] = (c - cStart)*4 + r; 1554 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1555 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1556 #if 1 1557 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1558 for (p = 0; p < 2; ++p) { 1559 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); 1560 } 1561 #endif 1562 } 1563 } 1564 /* Old vertices have identical supports */ 1565 for (v = vStart; v < vEnd; ++v) { 1566 const PetscInt newp = vStartNew + (v - vStart); 1567 const PetscInt *support, *cone; 1568 PetscInt size, s; 1569 1570 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1571 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1572 for (s = 0; s < size; ++s) { 1573 PetscInt r = 0; 1574 1575 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1576 if (cone[1] == v) r = 1; 1577 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1578 } 1579 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1580 #if 1 1581 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1582 for (p = 0; p < size; ++p) { 1583 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); 1584 } 1585 #endif 1586 } 1587 /* Face vertices have 2 + cells supports */ 1588 for (f = fStart; f < fEnd; ++f) { 1589 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1590 const PetscInt *cone, *support; 1591 PetscInt size, s; 1592 1593 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1594 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1595 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1596 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1597 for (s = 0; s < size; ++s) { 1598 PetscInt r = 0; 1599 1600 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1601 if (cone[1] == f) r = 1; 1602 else if (cone[2] == f) r = 2; 1603 else if (cone[3] == f) r = 3; 1604 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1605 } 1606 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1607 #if 1 1608 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1609 for (p = 0; p < 2+size; ++p) { 1610 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); 1611 } 1612 #endif 1613 } 1614 /* Cell vertices have 4 supports */ 1615 for (c = cStart; c < cEnd; ++c) { 1616 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1617 PetscInt supportNew[4]; 1618 1619 for (r = 0; r < 4; ++r) { 1620 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1621 } 1622 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1623 } 1624 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1625 break; 1626 case REFINER_HYBRID_SIMPLEX_2D: 1627 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1628 cMax = PetscMin(cEnd, cMax); 1629 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1630 fMax = PetscMin(fEnd, fMax); 1631 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1632 /* Interior cells have 3 faces */ 1633 for (c = cStart; c < cMax; ++c) { 1634 const PetscInt newp = cStartNew + (c - cStart)*4; 1635 const PetscInt *cone, *ornt; 1636 PetscInt coneNew[3], orntNew[3]; 1637 1638 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1639 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1640 /* A triangle */ 1641 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1642 orntNew[0] = ornt[0]; 1643 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1644 orntNew[1] = -2; 1645 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1646 orntNew[2] = ornt[2]; 1647 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1648 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1649 #if 1 1650 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); 1651 for (p = 0; p < 3; ++p) { 1652 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); 1653 } 1654 #endif 1655 /* B triangle */ 1656 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1657 orntNew[0] = ornt[0]; 1658 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1659 orntNew[1] = ornt[1]; 1660 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1661 orntNew[2] = -2; 1662 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1663 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1664 #if 1 1665 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew); 1666 for (p = 0; p < 3; ++p) { 1667 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); 1668 } 1669 #endif 1670 /* C triangle */ 1671 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1672 orntNew[0] = -2; 1673 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1674 orntNew[1] = ornt[1]; 1675 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1676 orntNew[2] = ornt[2]; 1677 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1678 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1679 #if 1 1680 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); 1681 for (p = 0; p < 3; ++p) { 1682 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); 1683 } 1684 #endif 1685 /* D triangle */ 1686 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1687 orntNew[0] = 0; 1688 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1689 orntNew[1] = 0; 1690 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1691 orntNew[2] = 0; 1692 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1693 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1694 #if 1 1695 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); 1696 for (p = 0; p < 3; ++p) { 1697 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); 1698 } 1699 #endif 1700 } 1701 /* 1702 2----3----3 1703 | | 1704 | B | 1705 | | 1706 0----4--- 1 1707 | | 1708 | A | 1709 | | 1710 0----2----1 1711 */ 1712 /* Hybrid cells have 4 faces */ 1713 for (c = cMax; c < cEnd; ++c) { 1714 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1715 const PetscInt *cone, *ornt; 1716 PetscInt coneNew[4], orntNew[4], r; 1717 1718 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1719 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1720 r = (ornt[0] < 0 ? 1 : 0); 1721 /* A quad */ 1722 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 1723 orntNew[0] = ornt[0]; 1724 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 1725 orntNew[1] = ornt[1]; 1726 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 1727 orntNew[2+r] = 0; 1728 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1729 orntNew[3-r] = 0; 1730 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1731 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1732 #if 1 1733 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); 1734 for (p = 0; p < 4; ++p) { 1735 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); 1736 } 1737 #endif 1738 /* B quad */ 1739 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 1740 orntNew[0] = ornt[0]; 1741 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 1742 orntNew[1] = ornt[1]; 1743 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1744 orntNew[2+r] = 0; 1745 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 1746 orntNew[3-r] = 0; 1747 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1748 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1749 #if 1 1750 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); 1751 for (p = 0; p < 4; ++p) { 1752 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); 1753 } 1754 #endif 1755 } 1756 /* Interior split faces have 2 vertices and the same cells as the parent */ 1757 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1758 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1759 for (f = fStart; f < fMax; ++f) { 1760 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1761 1762 for (r = 0; r < 2; ++r) { 1763 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1764 const PetscInt *cone, *ornt, *support; 1765 PetscInt coneNew[2], coneSize, c, supportSize, s; 1766 1767 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1768 coneNew[0] = vStartNew + (cone[0] - vStart); 1769 coneNew[1] = vStartNew + (cone[1] - vStart); 1770 coneNew[(r+1)%2] = newv; 1771 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1772 #if 1 1773 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1774 for (p = 0; p < 2; ++p) { 1775 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); 1776 } 1777 #endif 1778 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1779 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1780 for (s = 0; s < supportSize; ++s) { 1781 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1782 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1783 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1784 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 1785 if (support[s] >= cMax) { 1786 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 1787 } else { 1788 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1789 } 1790 } 1791 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1792 #if 1 1793 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1794 for (p = 0; p < supportSize; ++p) { 1795 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); 1796 } 1797 #endif 1798 } 1799 } 1800 /* Interior cell faces have 2 vertices and 2 cells */ 1801 for (c = cStart; c < cMax; ++c) { 1802 const PetscInt *cone; 1803 1804 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1805 for (r = 0; r < 3; ++r) { 1806 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1807 PetscInt coneNew[2]; 1808 PetscInt supportNew[2]; 1809 1810 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1811 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1812 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1813 #if 1 1814 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1815 for (p = 0; p < 2; ++p) { 1816 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); 1817 } 1818 #endif 1819 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1820 supportNew[1] = (c - cStart)*4 + 3; 1821 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1822 #if 1 1823 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1824 for (p = 0; p < 2; ++p) { 1825 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); 1826 } 1827 #endif 1828 } 1829 } 1830 /* Interior hybrid faces have 2 vertices and the same cells */ 1831 for (f = fMax; f < fEnd; ++f) { 1832 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1833 const PetscInt *cone, *ornt; 1834 const PetscInt *support; 1835 PetscInt coneNew[2]; 1836 PetscInt supportNew[2]; 1837 PetscInt size, s, r; 1838 1839 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1840 coneNew[0] = vStartNew + (cone[0] - vStart); 1841 coneNew[1] = vStartNew + (cone[1] - vStart); 1842 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1843 #if 1 1844 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1845 for (p = 0; p < 2; ++p) { 1846 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); 1847 } 1848 #endif 1849 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1850 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1851 for (s = 0; s < size; ++s) { 1852 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1853 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1854 for (r = 0; r < 2; ++r) { 1855 if (cone[r+2] == f) break; 1856 } 1857 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 1858 } 1859 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1860 #if 1 1861 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1862 for (p = 0; p < size; ++p) { 1863 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); 1864 } 1865 #endif 1866 } 1867 /* Cell hybrid faces have 2 vertices and 2 cells */ 1868 for (c = cMax; c < cEnd; ++c) { 1869 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1870 const PetscInt *cone; 1871 PetscInt coneNew[2]; 1872 PetscInt supportNew[2]; 1873 1874 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1875 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1876 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1877 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1878 #if 1 1879 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1880 for (p = 0; p < 2; ++p) { 1881 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); 1882 } 1883 #endif 1884 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1885 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1886 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1887 #if 1 1888 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1889 for (p = 0; p < 2; ++p) { 1890 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); 1891 } 1892 #endif 1893 } 1894 /* Old vertices have identical supports */ 1895 for (v = vStart; v < vEnd; ++v) { 1896 const PetscInt newp = vStartNew + (v - vStart); 1897 const PetscInt *support, *cone; 1898 PetscInt size, s; 1899 1900 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1901 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1902 for (s = 0; s < size; ++s) { 1903 if (support[s] >= fMax) { 1904 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1905 } else { 1906 PetscInt r = 0; 1907 1908 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1909 if (cone[1] == v) r = 1; 1910 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1911 } 1912 } 1913 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1914 #if 1 1915 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1916 for (p = 0; p < size; ++p) { 1917 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); 1918 } 1919 #endif 1920 } 1921 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1922 for (f = fStart; f < fMax; ++f) { 1923 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1924 const PetscInt *cone, *support; 1925 PetscInt size, newSize = 2, s; 1926 1927 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1928 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1929 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1930 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1931 for (s = 0; s < size; ++s) { 1932 PetscInt r = 0; 1933 1934 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1935 if (support[s] >= cMax) { 1936 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1937 1938 newSize += 1; 1939 } else { 1940 if (cone[1] == f) r = 1; 1941 else if (cone[2] == f) r = 2; 1942 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1943 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1944 1945 newSize += 2; 1946 } 1947 } 1948 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1949 #if 1 1950 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1951 for (p = 0; p < newSize; ++p) { 1952 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); 1953 } 1954 #endif 1955 } 1956 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1957 break; 1958 case REFINER_HYBRID_HEX_2D: 1959 /* Hybrid Hex 2D */ 1960 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1961 cMax = PetscMin(cEnd, cMax); 1962 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1963 fMax = PetscMin(fEnd, fMax); 1964 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1965 /* Interior cells have 4 faces */ 1966 for (c = cStart; c < cMax; ++c) { 1967 const PetscInt newp = cStartNew + (c - cStart)*4; 1968 const PetscInt *cone, *ornt; 1969 PetscInt coneNew[4], orntNew[4]; 1970 1971 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1972 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1973 /* A quad */ 1974 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1975 orntNew[0] = ornt[0]; 1976 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1977 orntNew[1] = 0; 1978 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1979 orntNew[2] = -2; 1980 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1981 orntNew[3] = ornt[3]; 1982 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1983 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1984 #if 1 1985 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); 1986 for (p = 0; p < 4; ++p) { 1987 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); 1988 } 1989 #endif 1990 /* B quad */ 1991 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1992 orntNew[0] = ornt[0]; 1993 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1994 orntNew[1] = ornt[1]; 1995 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1996 orntNew[2] = 0; 1997 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1998 orntNew[3] = -2; 1999 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2000 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2001 #if 1 2002 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); 2003 for (p = 0; p < 4; ++p) { 2004 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); 2005 } 2006 #endif 2007 /* C quad */ 2008 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2009 orntNew[0] = -2; 2010 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2011 orntNew[1] = ornt[1]; 2012 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2013 orntNew[2] = ornt[2]; 2014 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2015 orntNew[3] = 0; 2016 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2017 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2018 #if 1 2019 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); 2020 for (p = 0; p < 4; ++p) { 2021 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); 2022 } 2023 #endif 2024 /* D quad */ 2025 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2026 orntNew[0] = 0; 2027 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2028 orntNew[1] = -2; 2029 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2030 orntNew[2] = ornt[2]; 2031 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2032 orntNew[3] = ornt[3]; 2033 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2034 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2035 #if 1 2036 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); 2037 for (p = 0; p < 4; ++p) { 2038 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); 2039 } 2040 #endif 2041 } 2042 /* 2043 2----3----3 2044 | | 2045 | B | 2046 | | 2047 0----4--- 1 2048 | | 2049 | A | 2050 | | 2051 0----2----1 2052 */ 2053 /* Hybrid cells have 4 faces */ 2054 for (c = cMax; c < cEnd; ++c) { 2055 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2056 const PetscInt *cone, *ornt; 2057 PetscInt coneNew[4], orntNew[4]; 2058 2059 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2060 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2061 /* A quad */ 2062 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2063 orntNew[0] = ornt[0]; 2064 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2065 orntNew[1] = ornt[1]; 2066 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 2067 orntNew[2] = 0; 2068 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2069 orntNew[3] = 0; 2070 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2071 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2072 #if 1 2073 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); 2074 for (p = 0; p < 4; ++p) { 2075 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); 2076 } 2077 #endif 2078 /* B quad */ 2079 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2080 orntNew[0] = ornt[0]; 2081 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2082 orntNew[1] = ornt[1]; 2083 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2084 orntNew[2] = 0; 2085 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 2086 orntNew[3] = 0; 2087 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2088 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2089 #if 1 2090 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); 2091 for (p = 0; p < 4; ++p) { 2092 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); 2093 } 2094 #endif 2095 } 2096 /* Interior split faces have 2 vertices and the same cells as the parent */ 2097 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2098 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2099 for (f = fStart; f < fMax; ++f) { 2100 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2101 2102 for (r = 0; r < 2; ++r) { 2103 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2104 const PetscInt *cone, *ornt, *support; 2105 PetscInt coneNew[2], coneSize, c, supportSize, s; 2106 2107 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2108 coneNew[0] = vStartNew + (cone[0] - vStart); 2109 coneNew[1] = vStartNew + (cone[1] - vStart); 2110 coneNew[(r+1)%2] = newv; 2111 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2112 #if 1 2113 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2114 for (p = 0; p < 2; ++p) { 2115 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); 2116 } 2117 #endif 2118 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2119 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2120 for (s = 0; s < supportSize; ++s) { 2121 if (support[s] >= cMax) { 2122 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2123 } else { 2124 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2125 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2126 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2127 for (c = 0; c < coneSize; ++c) { 2128 if (cone[c] == f) break; 2129 } 2130 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2131 } 2132 } 2133 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2134 #if 1 2135 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2136 for (p = 0; p < supportSize; ++p) { 2137 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); 2138 } 2139 #endif 2140 } 2141 } 2142 /* Interior cell faces have 2 vertices and 2 cells */ 2143 for (c = cStart; c < cMax; ++c) { 2144 const PetscInt *cone; 2145 2146 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2147 for (r = 0; r < 4; ++r) { 2148 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2149 PetscInt coneNew[2], supportNew[2]; 2150 2151 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2152 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2153 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2154 #if 1 2155 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2156 for (p = 0; p < 2; ++p) { 2157 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); 2158 } 2159 #endif 2160 supportNew[0] = (c - cStart)*4 + r; 2161 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2162 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2163 #if 1 2164 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2165 for (p = 0; p < 2; ++p) { 2166 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); 2167 } 2168 #endif 2169 } 2170 } 2171 /* Hybrid faces have 2 vertices and the same cells */ 2172 for (f = fMax; f < fEnd; ++f) { 2173 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 2174 const PetscInt *cone, *support; 2175 PetscInt coneNew[2], supportNew[2]; 2176 PetscInt size, s, r; 2177 2178 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2179 coneNew[0] = vStartNew + (cone[0] - vStart); 2180 coneNew[1] = vStartNew + (cone[1] - vStart); 2181 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2182 #if 1 2183 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2184 for (p = 0; p < 2; ++p) { 2185 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); 2186 } 2187 #endif 2188 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2189 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2190 for (s = 0; s < size; ++s) { 2191 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2192 for (r = 0; r < 2; ++r) { 2193 if (cone[r+2] == f) break; 2194 } 2195 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2196 } 2197 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2198 #if 1 2199 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2200 for (p = 0; p < size; ++p) { 2201 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); 2202 } 2203 #endif 2204 } 2205 /* Cell hybrid faces have 2 vertices and 2 cells */ 2206 for (c = cMax; c < cEnd; ++c) { 2207 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2208 const PetscInt *cone; 2209 PetscInt coneNew[2], supportNew[2]; 2210 2211 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2212 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2213 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2214 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2215 #if 1 2216 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2217 for (p = 0; p < 2; ++p) { 2218 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); 2219 } 2220 #endif 2221 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2222 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2223 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2224 #if 1 2225 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2226 for (p = 0; p < 2; ++p) { 2227 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); 2228 } 2229 #endif 2230 } 2231 /* Old vertices have identical supports */ 2232 for (v = vStart; v < vEnd; ++v) { 2233 const PetscInt newp = vStartNew + (v - vStart); 2234 const PetscInt *support, *cone; 2235 PetscInt size, s; 2236 2237 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2238 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2239 for (s = 0; s < size; ++s) { 2240 if (support[s] >= fMax) { 2241 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2242 } else { 2243 PetscInt r = 0; 2244 2245 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2246 if (cone[1] == v) r = 1; 2247 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2248 } 2249 } 2250 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2251 #if 1 2252 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2253 for (p = 0; p < size; ++p) { 2254 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); 2255 } 2256 #endif 2257 } 2258 /* Face vertices have 2 + cells supports */ 2259 for (f = fStart; f < fMax; ++f) { 2260 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2261 const PetscInt *cone, *support; 2262 PetscInt size, s; 2263 2264 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2265 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2266 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2267 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2268 for (s = 0; s < size; ++s) { 2269 PetscInt r = 0; 2270 2271 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2272 if (support[s] >= cMax) { 2273 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2274 } else { 2275 if (cone[1] == f) r = 1; 2276 else if (cone[2] == f) r = 2; 2277 else if (cone[3] == f) r = 3; 2278 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2279 } 2280 } 2281 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2282 #if 1 2283 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2284 for (p = 0; p < 2+size; ++p) { 2285 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); 2286 } 2287 #endif 2288 } 2289 /* Cell vertices have 4 supports */ 2290 for (c = cStart; c < cMax; ++c) { 2291 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2292 PetscInt supportNew[4]; 2293 2294 for (r = 0; r < 4; ++r) { 2295 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2296 } 2297 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2298 } 2299 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2300 break; 2301 case REFINER_SIMPLEX_3D: 2302 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2303 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2304 for (c = cStart; c < cEnd; ++c) { 2305 const PetscInt newp = cStartNew + (c - cStart)*8; 2306 const PetscInt *cone, *ornt; 2307 PetscInt coneNew[4], orntNew[4]; 2308 2309 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2310 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2311 /* A tetrahedron: {0, a, c, d} */ 2312 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2313 orntNew[0] = ornt[0]; 2314 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2315 orntNew[1] = ornt[1]; 2316 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2317 orntNew[2] = ornt[2]; 2318 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2319 orntNew[3] = 0; 2320 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2321 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2322 #if 1 2323 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); 2324 for (p = 0; p < 4; ++p) { 2325 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); 2326 } 2327 #endif 2328 /* B tetrahedron: {a, 1, b, e} */ 2329 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2330 orntNew[0] = ornt[0]; 2331 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2332 orntNew[1] = ornt[1]; 2333 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2334 orntNew[2] = 0; 2335 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2336 orntNew[3] = ornt[3]; 2337 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2338 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2339 #if 1 2340 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); 2341 for (p = 0; p < 4; ++p) { 2342 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); 2343 } 2344 #endif 2345 /* C tetrahedron: {c, b, 2, f} */ 2346 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2347 orntNew[0] = ornt[0]; 2348 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2349 orntNew[1] = 0; 2350 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2351 orntNew[2] = ornt[2]; 2352 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2353 orntNew[3] = ornt[3]; 2354 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2355 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2356 #if 1 2357 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); 2358 for (p = 0; p < 4; ++p) { 2359 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); 2360 } 2361 #endif 2362 /* D tetrahedron: {d, e, f, 3} */ 2363 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2364 orntNew[0] = 0; 2365 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2366 orntNew[1] = ornt[1]; 2367 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2368 orntNew[2] = ornt[2]; 2369 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2370 orntNew[3] = ornt[3]; 2371 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2372 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2373 #if 1 2374 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); 2375 for (p = 0; p < 4; ++p) { 2376 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); 2377 } 2378 #endif 2379 /* A' tetrahedron: {c, d, a, f} */ 2380 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2381 orntNew[0] = -3; 2382 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2383 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2384 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2385 orntNew[2] = 0; 2386 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2387 orntNew[3] = 2; 2388 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2389 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2390 #if 1 2391 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); 2392 for (p = 0; p < 4; ++p) { 2393 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); 2394 } 2395 #endif 2396 /* B' tetrahedron: {e, b, a, f} */ 2397 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2398 orntNew[0] = -2; 2399 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 2400 orntNew[1] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 1)+1) : GetTetSomething_Static(ornt[3], 1); 2401 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2402 orntNew[2] = 0; 2403 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2404 orntNew[3] = 0; 2405 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2406 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2407 #if 1 2408 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); 2409 for (p = 0; p < 4; ++p) { 2410 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); 2411 } 2412 #endif 2413 /* C' tetrahedron: {f, a, c, b} */ 2414 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2415 orntNew[0] = -2; 2416 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2417 orntNew[1] = -2; 2418 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2419 orntNew[2] = -1; 2420 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 2421 orntNew[3] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2422 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2423 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2424 #if 1 2425 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); 2426 for (p = 0; p < 4; ++p) { 2427 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); 2428 } 2429 #endif 2430 /* D' tetrahedron: {f, a, e, d} */ 2431 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2432 orntNew[0] = -2; 2433 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2434 orntNew[1] = -1; 2435 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2436 orntNew[2] = -2; 2437 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 2438 orntNew[3] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 1)+1) : GetTetSomething_Static(ornt[1], 1); 2439 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2440 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2441 #if 1 2442 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); 2443 for (p = 0; p < 4; ++p) { 2444 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); 2445 } 2446 #endif 2447 } 2448 /* Split faces have 3 edges and the same cells as the parent */ 2449 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2450 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2451 for (f = fStart; f < fEnd; ++f) { 2452 const PetscInt newp = fStartNew + (f - fStart)*4; 2453 const PetscInt *cone, *ornt, *support; 2454 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2455 2456 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2457 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2458 /* A triangle */ 2459 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2460 orntNew[0] = ornt[0]; 2461 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2462 orntNew[1] = -2; 2463 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2464 orntNew[2] = ornt[2]; 2465 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2466 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2467 #if 1 2468 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); 2469 for (p = 0; p < 3; ++p) { 2470 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); 2471 } 2472 #endif 2473 /* B triangle */ 2474 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2475 orntNew[0] = ornt[0]; 2476 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2477 orntNew[1] = ornt[1]; 2478 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2479 orntNew[2] = -2; 2480 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2481 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2482 #if 1 2483 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); 2484 for (p = 0; p < 3; ++p) { 2485 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); 2486 } 2487 #endif 2488 /* C triangle */ 2489 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2490 orntNew[0] = -2; 2491 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2492 orntNew[1] = ornt[1]; 2493 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2494 orntNew[2] = ornt[2]; 2495 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2496 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2497 #if 1 2498 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); 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 /* D triangle */ 2504 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2505 orntNew[0] = 0; 2506 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2507 orntNew[1] = 0; 2508 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2509 orntNew[2] = 0; 2510 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2511 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2512 #if 1 2513 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); 2514 for (p = 0; p < 3; ++p) { 2515 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); 2516 } 2517 #endif 2518 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2519 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2520 for (r = 0; r < 4; ++r) { 2521 for (s = 0; s < supportSize; ++s) { 2522 PetscInt subf; 2523 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2524 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2525 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2526 for (c = 0; c < coneSize; ++c) { 2527 if (cone[c] == f) break; 2528 } 2529 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2530 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2531 } 2532 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2533 #if 1 2534 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); 2535 for (p = 0; p < supportSize; ++p) { 2536 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); 2537 } 2538 #endif 2539 } 2540 } 2541 /* Interior faces have 3 edges and 2 cells */ 2542 for (c = cStart; c < cEnd; ++c) { 2543 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2544 const PetscInt *cone, *ornt; 2545 PetscInt coneNew[3], orntNew[3]; 2546 PetscInt supportNew[2]; 2547 2548 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2549 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2550 /* Face A: {c, a, d} */ 2551 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2552 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2553 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2554 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2555 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2556 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2557 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2558 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2559 #if 1 2560 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2561 for (p = 0; p < 3; ++p) { 2562 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); 2563 } 2564 #endif 2565 supportNew[0] = (c - cStart)*8 + 0; 2566 supportNew[1] = (c - cStart)*8 + 0+4; 2567 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2568 #if 1 2569 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2570 for (p = 0; p < 2; ++p) { 2571 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); 2572 } 2573 #endif 2574 ++newp; 2575 /* Face B: {a, b, e} */ 2576 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2577 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2578 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2579 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2580 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2581 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2582 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2583 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2584 #if 1 2585 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2586 for (p = 0; p < 3; ++p) { 2587 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); 2588 } 2589 #endif 2590 supportNew[0] = (c - cStart)*8 + 1; 2591 supportNew[1] = (c - cStart)*8 + 1+4; 2592 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2593 #if 1 2594 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2595 for (p = 0; p < 2; ++p) { 2596 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); 2597 } 2598 #endif 2599 ++newp; 2600 /* Face C: {c, f, b} */ 2601 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2602 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2603 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2604 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2605 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2606 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2607 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2608 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2609 #if 1 2610 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2611 for (p = 0; p < 3; ++p) { 2612 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); 2613 } 2614 #endif 2615 supportNew[0] = (c - cStart)*8 + 2; 2616 supportNew[1] = (c - cStart)*8 + 2+4; 2617 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2618 #if 1 2619 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2620 for (p = 0; p < 2; ++p) { 2621 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); 2622 } 2623 #endif 2624 ++newp; 2625 /* Face D: {d, e, f} */ 2626 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2627 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2628 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2629 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2630 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2631 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2632 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2633 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2634 #if 1 2635 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2636 for (p = 0; p < 3; ++p) { 2637 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); 2638 } 2639 #endif 2640 supportNew[0] = (c - cStart)*8 + 3; 2641 supportNew[1] = (c - cStart)*8 + 3+4; 2642 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2643 #if 1 2644 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2645 for (p = 0; p < 2; ++p) { 2646 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); 2647 } 2648 #endif 2649 ++newp; 2650 /* Face E: {d, f, a} */ 2651 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2652 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2653 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2654 orntNew[1] = -2; 2655 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2656 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2657 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2658 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2659 #if 1 2660 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2661 for (p = 0; p < 3; ++p) { 2662 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); 2663 } 2664 #endif 2665 supportNew[0] = (c - cStart)*8 + 0+4; 2666 supportNew[1] = (c - cStart)*8 + 3+4; 2667 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2668 #if 1 2669 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2670 for (p = 0; p < 2; ++p) { 2671 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); 2672 } 2673 #endif 2674 ++newp; 2675 /* Face F: {c, a, f} */ 2676 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2677 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2678 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2679 orntNew[1] = 0; 2680 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2681 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2682 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2683 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2684 #if 1 2685 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2686 for (p = 0; p < 3; ++p) { 2687 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); 2688 } 2689 #endif 2690 supportNew[0] = (c - cStart)*8 + 0+4; 2691 supportNew[1] = (c - cStart)*8 + 2+4; 2692 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2693 #if 1 2694 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2695 for (p = 0; p < 2; ++p) { 2696 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); 2697 } 2698 #endif 2699 ++newp; 2700 /* Face G: {e, a, f} */ 2701 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2702 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2703 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2704 orntNew[1] = 0; 2705 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2706 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2707 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2708 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2709 #if 1 2710 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2711 for (p = 0; p < 3; ++p) { 2712 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); 2713 } 2714 #endif 2715 supportNew[0] = (c - cStart)*8 + 1+4; 2716 supportNew[1] = (c - cStart)*8 + 3+4; 2717 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2718 #if 1 2719 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2720 for (p = 0; p < 2; ++p) { 2721 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); 2722 } 2723 #endif 2724 ++newp; 2725 /* Face H: {a, b, f} */ 2726 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2727 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2728 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2729 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2730 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2731 orntNew[2] = -2; 2732 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2733 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2734 #if 1 2735 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2736 for (p = 0; p < 3; ++p) { 2737 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); 2738 } 2739 #endif 2740 supportNew[0] = (c - cStart)*8 + 1+4; 2741 supportNew[1] = (c - cStart)*8 + 2+4; 2742 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2743 #if 1 2744 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2745 for (p = 0; p < 2; ++p) { 2746 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); 2747 } 2748 #endif 2749 ++newp; 2750 } 2751 /* Split Edges have 2 vertices and the same faces as the parent */ 2752 for (e = eStart; e < eEnd; ++e) { 2753 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2754 2755 for (r = 0; r < 2; ++r) { 2756 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2757 const PetscInt *cone, *ornt, *support; 2758 PetscInt coneNew[2], coneSize, c, supportSize, s; 2759 2760 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2761 coneNew[0] = vStartNew + (cone[0] - vStart); 2762 coneNew[1] = vStartNew + (cone[1] - vStart); 2763 coneNew[(r+1)%2] = newv; 2764 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2765 #if 1 2766 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2767 for (p = 0; p < 2; ++p) { 2768 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); 2769 } 2770 #endif 2771 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2772 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2773 for (s = 0; s < supportSize; ++s) { 2774 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2775 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2776 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2777 for (c = 0; c < coneSize; ++c) { 2778 if (cone[c] == e) break; 2779 } 2780 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2781 } 2782 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2783 #if 1 2784 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2785 for (p = 0; p < supportSize; ++p) { 2786 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); 2787 } 2788 #endif 2789 } 2790 } 2791 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2792 for (f = fStart; f < fEnd; ++f) { 2793 const PetscInt *cone, *ornt, *support; 2794 PetscInt coneSize, supportSize, s; 2795 2796 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2797 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2798 for (r = 0; r < 3; ++r) { 2799 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2800 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2801 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2802 -1, -1, 1, 6, 0, 4, 2803 2, 5, 3, 4, -1, -1, 2804 -1, -1, 3, 6, 2, 7}; 2805 2806 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2807 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2808 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2809 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2810 #if 1 2811 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2812 for (p = 0; p < 2; ++p) { 2813 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); 2814 } 2815 #endif 2816 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2817 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2818 for (s = 0; s < supportSize; ++s) { 2819 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2820 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2821 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2822 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2823 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2824 er = GetTetSomethingInverse_Static(ornt[c], r); 2825 if (er == eint[c]) { 2826 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2827 } else { 2828 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2829 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2830 } 2831 } 2832 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2833 #if 1 2834 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2835 for (p = 0; p < intFaces; ++p) { 2836 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); 2837 } 2838 #endif 2839 } 2840 } 2841 /* Interior edges have 2 vertices and 4 faces */ 2842 for (c = cStart; c < cEnd; ++c) { 2843 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2844 const PetscInt *cone, *ornt, *fcone; 2845 PetscInt coneNew[2], supportNew[4], find; 2846 2847 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2848 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2849 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2850 find = GetTriEdge_Static(ornt[0], 0); 2851 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2852 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2853 find = GetTriEdge_Static(ornt[2], 1); 2854 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2855 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2856 #if 1 2857 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2858 for (p = 0; p < 2; ++p) { 2859 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); 2860 } 2861 #endif 2862 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2863 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2864 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2865 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2866 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2867 #if 1 2868 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2869 for (p = 0; p < 4; ++p) { 2870 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); 2871 } 2872 #endif 2873 } 2874 /* Old vertices have identical supports */ 2875 for (v = vStart; v < vEnd; ++v) { 2876 const PetscInt newp = vStartNew + (v - vStart); 2877 const PetscInt *support, *cone; 2878 PetscInt size, s; 2879 2880 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2881 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2882 for (s = 0; s < size; ++s) { 2883 PetscInt r = 0; 2884 2885 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2886 if (cone[1] == v) r = 1; 2887 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2888 } 2889 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2890 #if 1 2891 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2892 for (p = 0; p < size; ++p) { 2893 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); 2894 } 2895 #endif 2896 } 2897 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2898 for (e = eStart; e < eEnd; ++e) { 2899 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2900 const PetscInt *cone, *support; 2901 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2902 2903 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2904 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2905 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2906 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2907 for (s = 0; s < size; ++s) { 2908 PetscInt r = 0; 2909 2910 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2911 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2912 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2913 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2914 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2915 } 2916 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2917 for (s = 0; s < starSize*2; s += 2) { 2918 const PetscInt *cone, *ornt; 2919 PetscInt e01, e23; 2920 2921 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2922 /* Check edge 0-1 */ 2923 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2924 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2925 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2926 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2927 /* Check edge 2-3 */ 2928 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2929 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2930 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2931 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2932 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2933 } 2934 } 2935 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2936 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2937 #if 1 2938 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2939 for (p = 0; p < 2+size*2+cellSize; ++p) { 2940 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); 2941 } 2942 #endif 2943 } 2944 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2945 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2946 break; 2947 case REFINER_HYBRID_SIMPLEX_3D: 2948 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2949 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2950 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2951 for (c = cStart; c < cMax; ++c) { 2952 const PetscInt newp = cStartNew + (c - cStart)*8; 2953 const PetscInt *cone, *ornt; 2954 PetscInt coneNew[4], orntNew[4]; 2955 2956 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2957 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2958 /* A tetrahedron: {0, a, c, d} */ 2959 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2960 orntNew[0] = ornt[0]; 2961 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2962 orntNew[1] = ornt[1]; 2963 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2964 orntNew[2] = ornt[2]; 2965 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2966 orntNew[3] = 0; 2967 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2968 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2969 #if 1 2970 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); 2971 for (p = 0; p < 4; ++p) { 2972 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); 2973 } 2974 #endif 2975 /* B tetrahedron: {a, 1, b, e} */ 2976 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2977 orntNew[0] = ornt[0]; 2978 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2979 orntNew[1] = ornt[1]; 2980 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2981 orntNew[2] = 0; 2982 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2983 orntNew[3] = ornt[3]; 2984 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2985 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2986 #if 1 2987 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); 2988 for (p = 0; p < 4; ++p) { 2989 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); 2990 } 2991 #endif 2992 /* C tetrahedron: {c, b, 2, f} */ 2993 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2994 orntNew[0] = ornt[0]; 2995 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2996 orntNew[1] = 0; 2997 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2998 orntNew[2] = ornt[2]; 2999 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3000 orntNew[3] = ornt[3]; 3001 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3002 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3003 #if 1 3004 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); 3005 for (p = 0; p < 4; ++p) { 3006 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); 3007 } 3008 #endif 3009 /* D tetrahedron: {d, e, f, 3} */ 3010 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3011 orntNew[0] = 0; 3012 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3013 orntNew[1] = ornt[1]; 3014 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3015 orntNew[2] = ornt[2]; 3016 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3017 orntNew[3] = ornt[3]; 3018 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3019 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3020 #if 1 3021 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); 3022 for (p = 0; p < 4; ++p) { 3023 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); 3024 } 3025 #endif 3026 /* A' tetrahedron: {d, a, c, f} */ 3027 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3028 orntNew[0] = -3; 3029 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3030 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 3031 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3032 orntNew[2] = 0; 3033 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3034 orntNew[3] = 2; 3035 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3036 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3037 #if 1 3038 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); 3039 for (p = 0; p < 4; ++p) { 3040 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); 3041 } 3042 #endif 3043 /* B' tetrahedron: {e, b, a, f} */ 3044 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3045 orntNew[0] = -3; 3046 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3047 orntNew[1] = 1; 3048 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3049 orntNew[2] = 0; 3050 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 3051 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 3052 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3053 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3054 #if 1 3055 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); 3056 for (p = 0; p < 4; ++p) { 3057 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); 3058 } 3059 #endif 3060 /* C' tetrahedron: {b, f, c, a} */ 3061 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3062 orntNew[0] = -3; 3063 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 3064 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 3065 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3066 orntNew[2] = -3; 3067 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3068 orntNew[3] = -2; 3069 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3070 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3071 #if 1 3072 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); 3073 for (p = 0; p < 4; ++p) { 3074 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); 3075 } 3076 #endif 3077 /* D' tetrahedron: {f, e, d, a} */ 3078 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3079 orntNew[0] = -3; 3080 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3081 orntNew[1] = -3; 3082 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 3083 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 3084 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3085 orntNew[3] = -3; 3086 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3087 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3088 #if 1 3089 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); 3090 for (p = 0; p < 4; ++p) { 3091 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); 3092 } 3093 #endif 3094 } 3095 /* Hybrid cells have 5 faces */ 3096 for (c = cMax; c < cEnd; ++c) { 3097 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 3098 const PetscInt *cone, *ornt, *fornt; 3099 PetscInt coneNew[5], orntNew[5], o, of, i; 3100 3101 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3102 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3103 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 3104 o = ornt[0] < 0 ? -1 : 1; 3105 for (r = 0; r < 3; ++r) { 3106 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 3107 orntNew[0] = ornt[0]; 3108 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 3109 orntNew[1] = ornt[1]; 3110 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 3111 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 3112 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 3113 orntNew[i] = 0; 3114 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 3115 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 3116 orntNew[i] = 0; 3117 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 3118 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 3119 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); 3120 orntNew[i] = 0; 3121 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3122 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3123 #if 1 3124 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); 3125 for (p = 0; p < 2; ++p) { 3126 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); 3127 } 3128 for (p = 2; p < 5; ++p) { 3129 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); 3130 } 3131 #endif 3132 } 3133 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 3134 orntNew[0] = 0; 3135 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3136 orntNew[1] = 0; 3137 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3138 orntNew[2] = 0; 3139 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3140 orntNew[3] = 0; 3141 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3142 orntNew[4] = 0; 3143 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3144 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3145 #if 1 3146 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); 3147 for (p = 0; p < 2; ++p) { 3148 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); 3149 } 3150 for (p = 2; p < 5; ++p) { 3151 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); 3152 } 3153 #endif 3154 } 3155 /* Split faces have 3 edges and the same cells as the parent */ 3156 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3157 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3158 for (f = fStart; f < fMax; ++f) { 3159 const PetscInt newp = fStartNew + (f - fStart)*4; 3160 const PetscInt *cone, *ornt, *support; 3161 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3162 3163 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3164 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3165 /* A triangle */ 3166 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3167 orntNew[0] = ornt[0]; 3168 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3169 orntNew[1] = -2; 3170 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3171 orntNew[2] = ornt[2]; 3172 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3173 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3174 #if 1 3175 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); 3176 for (p = 0; p < 3; ++p) { 3177 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); 3178 } 3179 #endif 3180 /* B triangle */ 3181 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3182 orntNew[0] = ornt[0]; 3183 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3184 orntNew[1] = ornt[1]; 3185 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3186 orntNew[2] = -2; 3187 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3188 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3189 #if 1 3190 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); 3191 for (p = 0; p < 3; ++p) { 3192 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); 3193 } 3194 #endif 3195 /* C triangle */ 3196 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3197 orntNew[0] = -2; 3198 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3199 orntNew[1] = ornt[1]; 3200 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3201 orntNew[2] = ornt[2]; 3202 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3203 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3204 #if 1 3205 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); 3206 for (p = 0; p < 3; ++p) { 3207 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); 3208 } 3209 #endif 3210 /* D triangle */ 3211 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3212 orntNew[0] = 0; 3213 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3214 orntNew[1] = 0; 3215 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3216 orntNew[2] = 0; 3217 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3218 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3219 #if 1 3220 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); 3221 for (p = 0; p < 3; ++p) { 3222 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); 3223 } 3224 #endif 3225 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3226 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3227 for (r = 0; r < 4; ++r) { 3228 for (s = 0; s < supportSize; ++s) { 3229 PetscInt subf; 3230 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3231 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3232 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3233 for (c = 0; c < coneSize; ++c) { 3234 if (cone[c] == f) break; 3235 } 3236 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3237 if (support[s] < cMax) { 3238 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3239 } else { 3240 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3241 } 3242 } 3243 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3244 #if 1 3245 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); 3246 for (p = 0; p < supportSize; ++p) { 3247 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); 3248 } 3249 #endif 3250 } 3251 } 3252 /* Interior cell faces have 3 edges and 2 cells */ 3253 for (c = cStart; c < cMax; ++c) { 3254 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3255 const PetscInt *cone, *ornt; 3256 PetscInt coneNew[3], orntNew[3]; 3257 PetscInt supportNew[2]; 3258 3259 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3260 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3261 /* Face A: {c, a, d} */ 3262 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3263 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3264 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3265 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3266 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 3267 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3268 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3269 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3270 #if 1 3271 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3272 for (p = 0; p < 3; ++p) { 3273 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); 3274 } 3275 #endif 3276 supportNew[0] = (c - cStart)*8 + 0; 3277 supportNew[1] = (c - cStart)*8 + 0+4; 3278 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3279 #if 1 3280 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3281 for (p = 0; p < 2; ++p) { 3282 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); 3283 } 3284 #endif 3285 ++newp; 3286 /* Face B: {a, b, e} */ 3287 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3288 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3289 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 3290 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3291 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3292 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3293 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3294 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3295 #if 1 3296 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); 3297 for (p = 0; p < 3; ++p) { 3298 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); 3299 } 3300 #endif 3301 supportNew[0] = (c - cStart)*8 + 1; 3302 supportNew[1] = (c - cStart)*8 + 1+4; 3303 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3304 #if 1 3305 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3306 for (p = 0; p < 2; ++p) { 3307 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); 3308 } 3309 #endif 3310 ++newp; 3311 /* Face C: {c, f, b} */ 3312 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3313 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3314 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3315 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3316 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 3317 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3318 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3319 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3320 #if 1 3321 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3322 for (p = 0; p < 3; ++p) { 3323 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); 3324 } 3325 #endif 3326 supportNew[0] = (c - cStart)*8 + 2; 3327 supportNew[1] = (c - cStart)*8 + 2+4; 3328 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3329 #if 1 3330 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3331 for (p = 0; p < 2; ++p) { 3332 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); 3333 } 3334 #endif 3335 ++newp; 3336 /* Face D: {d, e, f} */ 3337 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 3338 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3339 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3340 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3341 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3342 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3343 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3344 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3345 #if 1 3346 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3347 for (p = 0; p < 3; ++p) { 3348 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); 3349 } 3350 #endif 3351 supportNew[0] = (c - cStart)*8 + 3; 3352 supportNew[1] = (c - cStart)*8 + 3+4; 3353 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3354 #if 1 3355 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3356 for (p = 0; p < 2; ++p) { 3357 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); 3358 } 3359 #endif 3360 ++newp; 3361 /* Face E: {d, f, a} */ 3362 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3363 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3364 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3365 orntNew[1] = -2; 3366 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3367 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3368 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3369 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3370 #if 1 3371 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3372 for (p = 0; p < 3; ++p) { 3373 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); 3374 } 3375 #endif 3376 supportNew[0] = (c - cStart)*8 + 0+4; 3377 supportNew[1] = (c - cStart)*8 + 3+4; 3378 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3379 #if 1 3380 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3381 for (p = 0; p < 2; ++p) { 3382 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); 3383 } 3384 #endif 3385 ++newp; 3386 /* Face F: {c, a, f} */ 3387 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3388 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3389 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3390 orntNew[1] = 0; 3391 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3392 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3393 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3394 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3395 #if 1 3396 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3397 for (p = 0; p < 3; ++p) { 3398 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); 3399 } 3400 #endif 3401 supportNew[0] = (c - cStart)*8 + 0+4; 3402 supportNew[1] = (c - cStart)*8 + 2+4; 3403 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3404 #if 1 3405 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3406 for (p = 0; p < 2; ++p) { 3407 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); 3408 } 3409 #endif 3410 ++newp; 3411 /* Face G: {e, a, f} */ 3412 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3413 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3414 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3415 orntNew[1] = 0; 3416 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3417 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3418 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3419 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3420 #if 1 3421 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3422 for (p = 0; p < 3; ++p) { 3423 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); 3424 } 3425 #endif 3426 supportNew[0] = (c - cStart)*8 + 1+4; 3427 supportNew[1] = (c - cStart)*8 + 3+4; 3428 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3429 #if 1 3430 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3431 for (p = 0; p < 2; ++p) { 3432 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); 3433 } 3434 #endif 3435 ++newp; 3436 /* Face H: {a, b, f} */ 3437 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3438 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3439 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3440 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3441 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3442 orntNew[2] = -2; 3443 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3444 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3445 #if 1 3446 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3447 for (p = 0; p < 3; ++p) { 3448 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); 3449 } 3450 #endif 3451 supportNew[0] = (c - cStart)*8 + 1+4; 3452 supportNew[1] = (c - cStart)*8 + 2+4; 3453 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3454 #if 1 3455 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3456 for (p = 0; p < 2; ++p) { 3457 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); 3458 } 3459 #endif 3460 ++newp; 3461 } 3462 /* Hybrid split faces have 4 edges and same cells */ 3463 for (f = fMax; f < fEnd; ++f) { 3464 const PetscInt *cone, *ornt, *support; 3465 PetscInt coneNew[4], orntNew[4]; 3466 PetscInt supportNew[2], size, s, c; 3467 3468 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3469 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3470 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3471 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3472 for (r = 0; r < 2; ++r) { 3473 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3474 3475 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3476 orntNew[0] = ornt[0]; 3477 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3478 orntNew[1] = ornt[1]; 3479 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3480 orntNew[2+r] = 0; 3481 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3482 orntNew[3-r] = 0; 3483 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3484 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3485 #if 1 3486 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3487 for (p = 0; p < 2; ++p) { 3488 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); 3489 } 3490 for (p = 2; p < 4; ++p) { 3491 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); 3492 } 3493 #endif 3494 for (s = 0; s < size; ++s) { 3495 const PetscInt *coneCell, *orntCell, *fornt; 3496 PetscInt o, of; 3497 3498 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3499 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3500 o = orntCell[0] < 0 ? -1 : 1; 3501 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3502 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3503 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3504 of = fornt[c-2] < 0 ? -1 : 1; 3505 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3506 } 3507 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3508 #if 1 3509 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3510 for (p = 0; p < size; ++p) { 3511 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); 3512 } 3513 #endif 3514 } 3515 } 3516 /* Hybrid cell faces have 4 edges and 2 cells */ 3517 for (c = cMax; c < cEnd; ++c) { 3518 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3519 const PetscInt *cone, *ornt; 3520 PetscInt coneNew[4], orntNew[4]; 3521 PetscInt supportNew[2]; 3522 3523 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3524 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3525 for (r = 0; r < 3; ++r) { 3526 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3527 orntNew[0] = 0; 3528 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3529 orntNew[1] = 0; 3530 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3531 orntNew[2] = 0; 3532 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3533 orntNew[3] = 0; 3534 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3535 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3536 #if 1 3537 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); 3538 for (p = 0; p < 2; ++p) { 3539 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); 3540 } 3541 for (p = 2; p < 4; ++p) { 3542 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); 3543 } 3544 #endif 3545 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3546 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3547 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3548 #if 1 3549 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); 3550 for (p = 0; p < 2; ++p) { 3551 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); 3552 } 3553 #endif 3554 } 3555 } 3556 /* Interior split edges have 2 vertices and the same faces as the parent */ 3557 for (e = eStart; e < eMax; ++e) { 3558 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3559 3560 for (r = 0; r < 2; ++r) { 3561 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3562 const PetscInt *cone, *ornt, *support; 3563 PetscInt coneNew[2], coneSize, c, supportSize, s; 3564 3565 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3566 coneNew[0] = vStartNew + (cone[0] - vStart); 3567 coneNew[1] = vStartNew + (cone[1] - vStart); 3568 coneNew[(r+1)%2] = newv; 3569 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3570 #if 1 3571 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3572 for (p = 0; p < 2; ++p) { 3573 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); 3574 } 3575 #endif 3576 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3577 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3578 for (s = 0; s < supportSize; ++s) { 3579 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3580 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3581 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3582 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3583 if (support[s] < fMax) { 3584 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3585 } else { 3586 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3587 } 3588 } 3589 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3590 #if 1 3591 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3592 for (p = 0; p < supportSize; ++p) { 3593 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); 3594 } 3595 #endif 3596 } 3597 } 3598 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3599 for (f = fStart; f < fMax; ++f) { 3600 const PetscInt *cone, *ornt, *support; 3601 PetscInt coneSize, supportSize, s; 3602 3603 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3604 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3605 for (r = 0; r < 3; ++r) { 3606 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3607 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3608 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3609 -1, -1, 1, 6, 0, 4, 3610 2, 5, 3, 4, -1, -1, 3611 -1, -1, 3, 6, 2, 7}; 3612 3613 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3614 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3615 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3616 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3617 #if 1 3618 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3619 for (p = 0; p < 2; ++p) { 3620 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); 3621 } 3622 #endif 3623 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3624 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3625 for (s = 0; s < supportSize; ++s) { 3626 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3627 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3628 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3629 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3630 if (support[s] < cMax) { 3631 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3632 er = GetTetSomethingInverse_Static(ornt[c], r); 3633 if (er == eint[c]) { 3634 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3635 } else { 3636 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3637 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3638 } 3639 } else { 3640 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 3641 } 3642 } 3643 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3644 #if 1 3645 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3646 for (p = 0; p < intFaces; ++p) { 3647 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); 3648 } 3649 #endif 3650 } 3651 } 3652 /* Interior cell edges have 2 vertices and 4 faces */ 3653 for (c = cStart; c < cMax; ++c) { 3654 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3655 const PetscInt *cone, *ornt, *fcone; 3656 PetscInt coneNew[2], supportNew[4], find; 3657 3658 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3659 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3660 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3661 find = GetTriEdge_Static(ornt[0], 0); 3662 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3663 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3664 find = GetTriEdge_Static(ornt[2], 1); 3665 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3666 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3667 #if 1 3668 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3669 for (p = 0; p < 2; ++p) { 3670 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); 3671 } 3672 #endif 3673 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3674 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3675 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3676 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3677 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3678 #if 1 3679 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3680 for (p = 0; p < 4; ++p) { 3681 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); 3682 } 3683 #endif 3684 } 3685 /* Hybrid edges have two vertices and the same faces */ 3686 for (e = eMax; e < eEnd; ++e) { 3687 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3688 const PetscInt *cone, *support, *fcone; 3689 PetscInt coneNew[2], size, fsize, s; 3690 3691 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3692 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3693 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3694 coneNew[0] = vStartNew + (cone[0] - vStart); 3695 coneNew[1] = vStartNew + (cone[1] - vStart); 3696 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3697 #if 1 3698 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3699 for (p = 0; p < 2; ++p) { 3700 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); 3701 } 3702 #endif 3703 for (s = 0; s < size; ++s) { 3704 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3705 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3706 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3707 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3708 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3709 } 3710 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3711 #if 1 3712 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3713 for (p = 0; p < size; ++p) { 3714 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); 3715 } 3716 #endif 3717 } 3718 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3719 for (f = fMax; f < fEnd; ++f) { 3720 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3721 const PetscInt *cone, *support, *ccone, *cornt; 3722 PetscInt coneNew[2], size, csize, s; 3723 3724 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3725 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3726 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3727 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3728 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3729 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3730 #if 1 3731 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3732 for (p = 0; p < 2; ++p) { 3733 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); 3734 } 3735 #endif 3736 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3737 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3738 for (s = 0; s < size; ++s) { 3739 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3740 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3741 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3742 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3743 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]); 3744 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 3745 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 3746 } 3747 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3748 #if 1 3749 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3750 for (p = 0; p < 2+size*2; ++p) { 3751 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); 3752 } 3753 #endif 3754 } 3755 /* Interior vertices have identical supports */ 3756 for (v = vStart; v < vEnd; ++v) { 3757 const PetscInt newp = vStartNew + (v - vStart); 3758 const PetscInt *support, *cone; 3759 PetscInt size, s; 3760 3761 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3762 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3763 for (s = 0; s < size; ++s) { 3764 PetscInt r = 0; 3765 3766 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3767 if (cone[1] == v) r = 1; 3768 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3769 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3770 } 3771 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3772 #if 1 3773 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3774 for (p = 0; p < size; ++p) { 3775 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); 3776 } 3777 #endif 3778 } 3779 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3780 for (e = eStart; e < eMax; ++e) { 3781 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3782 const PetscInt *cone, *support; 3783 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3784 3785 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3786 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3787 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3788 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3789 for (s = 0; s < size; ++s) { 3790 PetscInt r = 0; 3791 3792 if (support[s] < fMax) { 3793 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3794 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3795 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3796 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3797 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3798 faceSize += 2; 3799 } else { 3800 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3801 ++faceSize; 3802 } 3803 } 3804 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3805 for (s = 0; s < starSize*2; s += 2) { 3806 const PetscInt *cone, *ornt; 3807 PetscInt e01, e23; 3808 3809 if ((star[s] >= cStart) && (star[s] < cMax)) { 3810 /* Check edge 0-1 */ 3811 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3812 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3813 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3814 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3815 /* Check edge 2-3 */ 3816 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3817 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3818 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3819 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3820 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3821 } 3822 } 3823 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3824 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3825 #if 1 3826 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3827 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3828 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); 3829 } 3830 #endif 3831 } 3832 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3833 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3834 break; 3835 case REFINER_HEX_3D: 3836 /* 3837 Bottom (viewed from top) Top 3838 1---------2---------2 7---------2---------6 3839 | | | | | | 3840 | B 2 C | | H 2 G | 3841 | | | | | | 3842 3----3----0----1----1 3----3----0----1----1 3843 | | | | | | 3844 | A 0 D | | E 0 F | 3845 | | | | | | 3846 0---------0---------3 4---------0---------5 3847 */ 3848 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3849 for (c = cStart; c < cEnd; ++c) { 3850 const PetscInt newp = (c - cStart)*8; 3851 const PetscInt *cone, *ornt; 3852 PetscInt coneNew[6], orntNew[6]; 3853 3854 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3855 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3856 /* A hex */ 3857 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3858 orntNew[0] = ornt[0]; 3859 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3860 orntNew[1] = 0; 3861 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3862 orntNew[2] = ornt[2]; 3863 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3864 orntNew[3] = 0; 3865 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3866 orntNew[4] = 0; 3867 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3868 orntNew[5] = ornt[5]; 3869 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3870 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3871 #if 1 3872 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); 3873 for (p = 0; p < 6; ++p) { 3874 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); 3875 } 3876 #endif 3877 /* B hex */ 3878 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3879 orntNew[0] = ornt[0]; 3880 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3881 orntNew[1] = 0; 3882 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3883 orntNew[2] = -1; 3884 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3885 orntNew[3] = ornt[3]; 3886 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3887 orntNew[4] = 0; 3888 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3889 orntNew[5] = ornt[5]; 3890 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3891 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3892 #if 1 3893 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); 3894 for (p = 0; p < 6; ++p) { 3895 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); 3896 } 3897 #endif 3898 /* C hex */ 3899 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3900 orntNew[0] = ornt[0]; 3901 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3902 orntNew[1] = 0; 3903 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3904 orntNew[2] = -1; 3905 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3906 orntNew[3] = ornt[3]; 3907 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3908 orntNew[4] = ornt[4]; 3909 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3910 orntNew[5] = -4; 3911 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3912 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3913 #if 1 3914 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); 3915 for (p = 0; p < 6; ++p) { 3916 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); 3917 } 3918 #endif 3919 /* D hex */ 3920 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3921 orntNew[0] = ornt[0]; 3922 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3923 orntNew[1] = 0; 3924 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3925 orntNew[2] = ornt[2]; 3926 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3927 orntNew[3] = 0; 3928 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3929 orntNew[4] = ornt[4]; 3930 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3931 orntNew[5] = -4; 3932 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3933 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3934 #if 1 3935 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); 3936 for (p = 0; p < 6; ++p) { 3937 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); 3938 } 3939 #endif 3940 /* E hex */ 3941 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3942 orntNew[0] = -4; 3943 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3944 orntNew[1] = ornt[1]; 3945 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3946 orntNew[2] = ornt[2]; 3947 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3948 orntNew[3] = 0; 3949 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3950 orntNew[4] = -1; 3951 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3952 orntNew[5] = ornt[5]; 3953 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3954 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3955 #if 1 3956 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); 3957 for (p = 0; p < 6; ++p) { 3958 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); 3959 } 3960 #endif 3961 /* F hex */ 3962 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3963 orntNew[0] = -4; 3964 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3965 orntNew[1] = ornt[1]; 3966 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3967 orntNew[2] = ornt[2]; 3968 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3969 orntNew[3] = -1; 3970 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3971 orntNew[4] = ornt[4]; 3972 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3973 orntNew[5] = 1; 3974 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3975 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3976 #if 1 3977 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); 3978 for (p = 0; p < 6; ++p) { 3979 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); 3980 } 3981 #endif 3982 /* G hex */ 3983 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3984 orntNew[0] = -4; 3985 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3986 orntNew[1] = ornt[1]; 3987 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3988 orntNew[2] = 0; 3989 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3990 orntNew[3] = ornt[3]; 3991 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3992 orntNew[4] = ornt[4]; 3993 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3994 orntNew[5] = -3; 3995 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3996 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3997 #if 1 3998 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); 3999 for (p = 0; p < 6; ++p) { 4000 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); 4001 } 4002 #endif 4003 /* H hex */ 4004 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4005 orntNew[0] = -4; 4006 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4007 orntNew[1] = ornt[1]; 4008 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4009 orntNew[2] = -1; 4010 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4011 orntNew[3] = ornt[3]; 4012 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4013 orntNew[4] = 3; 4014 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4015 orntNew[5] = ornt[5]; 4016 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4017 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4018 #if 1 4019 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); 4020 for (p = 0; p < 6; ++p) { 4021 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); 4022 } 4023 #endif 4024 } 4025 /* Split faces have 4 edges and the same cells as the parent */ 4026 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4027 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4028 for (f = fStart; f < fEnd; ++f) { 4029 for (r = 0; r < 4; ++r) { 4030 /* TODO: This can come from GetFaces_Internal() */ 4031 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}; 4032 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4033 const PetscInt *cone, *ornt, *support; 4034 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4035 4036 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4037 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4038 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4039 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4040 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4041 orntNew[(r+0)%4] = ornt[r]; 4042 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4043 orntNew[(r+1)%4] = 0; 4044 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4045 orntNew[(r+2)%4] = -2; 4046 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4047 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4048 #if 1 4049 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4050 for (p = 0; p < 4; ++p) { 4051 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4052 } 4053 #endif 4054 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4055 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4056 for (s = 0; s < supportSize; ++s) { 4057 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4058 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4059 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4060 for (c = 0; c < coneSize; ++c) { 4061 if (cone[c] == f) break; 4062 } 4063 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 4064 } 4065 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4066 #if 1 4067 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4068 for (p = 0; p < supportSize; ++p) { 4069 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); 4070 } 4071 #endif 4072 } 4073 } 4074 /* Interior faces have 4 edges and 2 cells */ 4075 for (c = cStart; c < cEnd; ++c) { 4076 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}; 4077 const PetscInt *cone, *ornt; 4078 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4079 4080 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4081 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4082 /* A-D face */ 4083 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 4084 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4085 orntNew[0] = 0; 4086 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4087 orntNew[1] = 0; 4088 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4089 orntNew[2] = -2; 4090 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4091 orntNew[3] = -2; 4092 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4093 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4094 #if 1 4095 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4096 for (p = 0; p < 4; ++p) { 4097 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4098 } 4099 #endif 4100 /* C-D face */ 4101 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 4102 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4103 orntNew[0] = 0; 4104 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4105 orntNew[1] = 0; 4106 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4107 orntNew[2] = -2; 4108 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4109 orntNew[3] = -2; 4110 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4111 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4112 #if 1 4113 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4114 for (p = 0; p < 4; ++p) { 4115 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4116 } 4117 #endif 4118 /* B-C face */ 4119 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 4120 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4121 orntNew[0] = -2; 4122 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4123 orntNew[1] = 0; 4124 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4125 orntNew[2] = 0; 4126 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4127 orntNew[3] = -2; 4128 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4129 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4130 #if 1 4131 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4132 for (p = 0; p < 4; ++p) { 4133 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4134 } 4135 #endif 4136 /* A-B face */ 4137 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 4138 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4139 orntNew[0] = -2; 4140 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4141 orntNew[1] = 0; 4142 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4143 orntNew[2] = 0; 4144 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4145 orntNew[3] = -2; 4146 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4147 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4148 #if 1 4149 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4150 for (p = 0; p < 4; ++p) { 4151 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4152 } 4153 #endif 4154 /* E-F face */ 4155 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 4156 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4157 orntNew[0] = -2; 4158 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4159 orntNew[1] = -2; 4160 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4161 orntNew[2] = 0; 4162 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4163 orntNew[3] = 0; 4164 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4165 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4166 #if 1 4167 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4168 for (p = 0; p < 4; ++p) { 4169 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4170 } 4171 #endif 4172 /* F-G face */ 4173 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 4174 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4175 orntNew[0] = -2; 4176 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4177 orntNew[1] = -2; 4178 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4179 orntNew[2] = 0; 4180 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4181 orntNew[3] = 0; 4182 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4183 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4184 #if 1 4185 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4186 for (p = 0; p < 4; ++p) { 4187 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4188 } 4189 #endif 4190 /* G-H face */ 4191 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 4192 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4193 orntNew[0] = -2; 4194 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4195 orntNew[1] = 0; 4196 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4197 orntNew[2] = 0; 4198 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4199 orntNew[3] = -2; 4200 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4201 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4202 #if 1 4203 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4204 for (p = 0; p < 4; ++p) { 4205 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4206 } 4207 #endif 4208 /* E-H face */ 4209 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 4210 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4211 orntNew[0] = -2; 4212 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4213 orntNew[1] = -2; 4214 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4215 orntNew[2] = 0; 4216 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4217 orntNew[3] = 0; 4218 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4219 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4220 #if 1 4221 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4222 for (p = 0; p < 4; ++p) { 4223 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4224 } 4225 #endif 4226 /* A-E face */ 4227 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 4228 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4229 orntNew[0] = 0; 4230 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4231 orntNew[1] = 0; 4232 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4233 orntNew[2] = -2; 4234 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4235 orntNew[3] = -2; 4236 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4237 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4238 #if 1 4239 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4240 for (p = 0; p < 4; ++p) { 4241 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4242 } 4243 #endif 4244 /* D-F face */ 4245 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 4246 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4247 orntNew[0] = -2; 4248 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4249 orntNew[1] = 0; 4250 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4251 orntNew[2] = 0; 4252 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4253 orntNew[3] = -2; 4254 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4255 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4256 #if 1 4257 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4258 for (p = 0; p < 4; ++p) { 4259 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); 4260 } 4261 #endif 4262 /* C-G face */ 4263 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 4264 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4265 orntNew[0] = -2; 4266 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4267 orntNew[1] = -2; 4268 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4269 orntNew[2] = 0; 4270 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4271 orntNew[3] = 0; 4272 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4273 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4274 #if 1 4275 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4276 for (p = 0; p < 4; ++p) { 4277 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); 4278 } 4279 #endif 4280 /* B-H face */ 4281 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 4282 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4283 orntNew[0] = 0; 4284 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4285 orntNew[1] = -2; 4286 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4287 orntNew[2] = -2; 4288 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4289 orntNew[3] = 0; 4290 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4291 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4292 #if 1 4293 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4294 for (p = 0; p < 4; ++p) { 4295 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); 4296 } 4297 #endif 4298 for (r = 0; r < 12; ++r) { 4299 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 4300 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4301 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4302 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4303 #if 1 4304 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4305 for (p = 0; p < 2; ++p) { 4306 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); 4307 } 4308 #endif 4309 } 4310 } 4311 /* Split edges have 2 vertices and the same faces as the parent */ 4312 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4313 for (e = eStart; e < eEnd; ++e) { 4314 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4315 4316 for (r = 0; r < 2; ++r) { 4317 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4318 const PetscInt *cone, *ornt, *support; 4319 PetscInt coneNew[2], coneSize, c, supportSize, s; 4320 4321 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4322 coneNew[0] = vStartNew + (cone[0] - vStart); 4323 coneNew[1] = vStartNew + (cone[1] - vStart); 4324 coneNew[(r+1)%2] = newv; 4325 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4326 #if 1 4327 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4328 for (p = 0; p < 2; ++p) { 4329 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); 4330 } 4331 #endif 4332 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4333 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4334 for (s = 0; s < supportSize; ++s) { 4335 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4336 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4337 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4338 for (c = 0; c < coneSize; ++c) { 4339 if (cone[c] == e) break; 4340 } 4341 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 4342 } 4343 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4344 #if 1 4345 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4346 for (p = 0; p < supportSize; ++p) { 4347 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); 4348 } 4349 #endif 4350 } 4351 } 4352 /* Face edges have 2 vertices and 2+cells faces */ 4353 for (f = fStart; f < fEnd; ++f) { 4354 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}; 4355 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4356 const PetscInt *cone, *coneCell, *orntCell, *support; 4357 PetscInt coneNew[2], coneSize, c, supportSize, s; 4358 4359 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4360 for (r = 0; r < 4; ++r) { 4361 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4362 4363 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4364 coneNew[1] = newv; 4365 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4366 #if 1 4367 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4368 for (p = 0; p < 2; ++p) { 4369 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); 4370 } 4371 #endif 4372 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4373 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4374 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4375 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4376 for (s = 0; s < supportSize; ++s) { 4377 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4378 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4379 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4380 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4381 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4382 } 4383 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4384 #if 1 4385 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4386 for (p = 0; p < 2+supportSize; ++p) { 4387 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); 4388 } 4389 #endif 4390 } 4391 } 4392 /* Cell edges have 2 vertices and 4 faces */ 4393 for (c = cStart; c < cEnd; ++c) { 4394 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}; 4395 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4396 const PetscInt *cone; 4397 PetscInt coneNew[2], supportNew[4]; 4398 4399 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4400 for (r = 0; r < 6; ++r) { 4401 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4402 4403 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4404 coneNew[1] = newv; 4405 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4406 #if 1 4407 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4408 for (p = 0; p < 2; ++p) { 4409 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); 4410 } 4411 #endif 4412 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4413 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4414 #if 1 4415 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4416 for (p = 0; p < 4; ++p) { 4417 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); 4418 } 4419 #endif 4420 } 4421 } 4422 /* Old vertices have identical supports */ 4423 for (v = vStart; v < vEnd; ++v) { 4424 const PetscInt newp = vStartNew + (v - vStart); 4425 const PetscInt *support, *cone; 4426 PetscInt size, s; 4427 4428 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4429 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4430 for (s = 0; s < size; ++s) { 4431 PetscInt r = 0; 4432 4433 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4434 if (cone[1] == v) r = 1; 4435 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4436 } 4437 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4438 #if 1 4439 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4440 for (p = 0; p < size; ++p) { 4441 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); 4442 } 4443 #endif 4444 } 4445 /* Edge vertices have 2 + faces supports */ 4446 for (e = eStart; e < eEnd; ++e) { 4447 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4448 const PetscInt *cone, *support; 4449 PetscInt size, s; 4450 4451 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4452 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4453 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4454 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4455 for (s = 0; s < size; ++s) { 4456 PetscInt r; 4457 4458 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4459 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4460 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 4461 } 4462 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4463 #if 1 4464 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4465 for (p = 0; p < 2+size; ++p) { 4466 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); 4467 } 4468 #endif 4469 } 4470 /* Face vertices have 4 + cells supports */ 4471 for (f = fStart; f < fEnd; ++f) { 4472 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4473 const PetscInt *cone, *support; 4474 PetscInt size, s; 4475 4476 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4477 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4478 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4479 for (s = 0; s < size; ++s) { 4480 PetscInt r; 4481 4482 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4483 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4484 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 4485 } 4486 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4487 #if 1 4488 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4489 for (p = 0; p < 4+size; ++p) { 4490 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); 4491 } 4492 #endif 4493 } 4494 /* Cell vertices have 6 supports */ 4495 for (c = cStart; c < cEnd; ++c) { 4496 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4497 PetscInt supportNew[6]; 4498 4499 for (r = 0; r < 6; ++r) { 4500 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4501 } 4502 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4503 } 4504 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4505 break; 4506 case REFINER_HYBRID_HEX_3D: 4507 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4508 /* 4509 Bottom (viewed from top) Top 4510 1---------2---------2 7---------2---------6 4511 | | | | | | 4512 | B 2 C | | H 2 G | 4513 | | | | | | 4514 3----3----0----1----1 3----3----0----1----1 4515 | | | | | | 4516 | A 0 D | | E 0 F | 4517 | | | | | | 4518 0---------0---------3 4---------0---------5 4519 */ 4520 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4521 for (c = cStart; c < cMax; ++c) { 4522 const PetscInt newp = (c - cStart)*8; 4523 const PetscInt *cone, *ornt; 4524 PetscInt coneNew[6], orntNew[6]; 4525 4526 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4527 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4528 /* A hex */ 4529 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4530 orntNew[0] = ornt[0]; 4531 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4532 orntNew[1] = 0; 4533 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4534 orntNew[2] = ornt[2]; 4535 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4536 orntNew[3] = 0; 4537 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4538 orntNew[4] = 0; 4539 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4540 orntNew[5] = ornt[5]; 4541 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4542 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4543 #if 1 4544 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); 4545 for (p = 0; p < 6; ++p) { 4546 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); 4547 } 4548 #endif 4549 /* B hex */ 4550 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4551 orntNew[0] = ornt[0]; 4552 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4553 orntNew[1] = 0; 4554 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4555 orntNew[2] = -1; 4556 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4557 orntNew[3] = ornt[3]; 4558 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4559 orntNew[4] = 0; 4560 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4561 orntNew[5] = ornt[5]; 4562 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4563 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4564 #if 1 4565 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); 4566 for (p = 0; p < 6; ++p) { 4567 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); 4568 } 4569 #endif 4570 /* C hex */ 4571 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4572 orntNew[0] = ornt[0]; 4573 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4574 orntNew[1] = 0; 4575 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4576 orntNew[2] = -1; 4577 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4578 orntNew[3] = ornt[3]; 4579 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4580 orntNew[4] = ornt[4]; 4581 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4582 orntNew[5] = -4; 4583 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4584 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4585 #if 1 4586 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); 4587 for (p = 0; p < 6; ++p) { 4588 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); 4589 } 4590 #endif 4591 /* D hex */ 4592 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4593 orntNew[0] = ornt[0]; 4594 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4595 orntNew[1] = 0; 4596 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4597 orntNew[2] = ornt[2]; 4598 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4599 orntNew[3] = 0; 4600 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4601 orntNew[4] = ornt[4]; 4602 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4603 orntNew[5] = -4; 4604 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4605 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4606 #if 1 4607 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); 4608 for (p = 0; p < 6; ++p) { 4609 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); 4610 } 4611 #endif 4612 /* E hex */ 4613 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4614 orntNew[0] = -4; 4615 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4616 orntNew[1] = ornt[1]; 4617 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4618 orntNew[2] = ornt[2]; 4619 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4620 orntNew[3] = 0; 4621 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4622 orntNew[4] = -1; 4623 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4624 orntNew[5] = ornt[5]; 4625 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4626 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4627 #if 1 4628 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); 4629 for (p = 0; p < 6; ++p) { 4630 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); 4631 } 4632 #endif 4633 /* F hex */ 4634 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4635 orntNew[0] = -4; 4636 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4637 orntNew[1] = ornt[1]; 4638 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4639 orntNew[2] = ornt[2]; 4640 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4641 orntNew[3] = -1; 4642 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4643 orntNew[4] = ornt[4]; 4644 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4645 orntNew[5] = 1; 4646 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4647 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4648 #if 1 4649 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); 4650 for (p = 0; p < 6; ++p) { 4651 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); 4652 } 4653 #endif 4654 /* G hex */ 4655 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4656 orntNew[0] = -4; 4657 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4658 orntNew[1] = ornt[1]; 4659 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4660 orntNew[2] = 0; 4661 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4662 orntNew[3] = ornt[3]; 4663 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4664 orntNew[4] = ornt[4]; 4665 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4666 orntNew[5] = -3; 4667 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4668 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4669 #if 1 4670 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); 4671 for (p = 0; p < 6; ++p) { 4672 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); 4673 } 4674 #endif 4675 /* H hex */ 4676 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4677 orntNew[0] = -4; 4678 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4679 orntNew[1] = ornt[1]; 4680 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4681 orntNew[2] = -1; 4682 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4683 orntNew[3] = ornt[3]; 4684 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4685 orntNew[4] = 3; 4686 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4687 orntNew[5] = ornt[5]; 4688 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4689 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4690 #if 1 4691 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); 4692 for (p = 0; p < 6; ++p) { 4693 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4694 } 4695 #endif 4696 } 4697 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4698 /* 4699 3---------2---------2 4700 | | | 4701 | D 2 C | 4702 | | | 4703 3----3----0----1----1 4704 | | | 4705 | A 0 B | 4706 | | | 4707 0---------0---------1 4708 */ 4709 for (c = cMax; c < cEnd; ++c) { 4710 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4711 const PetscInt *cone, *ornt, *fornt; 4712 PetscInt coneNew[6], orntNew[6], o, of, i; 4713 4714 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4715 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4716 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4717 o = ornt[0] < 0 ? -1 : 1; 4718 for (r = 0; r < 4; ++r) { 4719 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4720 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4721 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 4722 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]); 4723 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4724 orntNew[0] = ornt[0]; 4725 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4726 orntNew[1] = ornt[0]; 4727 of = fornt[edgeA] < 0 ? -1 : 1; 4728 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 4729 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 4730 orntNew[i] = ornt[edgeA]; 4731 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 4732 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4733 orntNew[i] = 0; 4734 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 4735 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4736 orntNew[i] = -2; 4737 of = fornt[edgeB] < 0 ? -1 : 1; 4738 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 4739 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 4740 orntNew[i] = ornt[edgeB]; 4741 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4742 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4743 #if 1 4744 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); 4745 for (p = 0; p < 2; ++p) { 4746 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); 4747 } 4748 for (p = 2; p < 6; ++p) { 4749 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); 4750 } 4751 #endif 4752 } 4753 } 4754 /* Interior split faces have 4 edges and the same cells as the parent */ 4755 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4756 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4757 for (f = fStart; f < fMax; ++f) { 4758 for (r = 0; r < 4; ++r) { 4759 /* TODO: This can come from GetFaces_Internal() */ 4760 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}; 4761 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4762 const PetscInt *cone, *ornt, *support; 4763 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4764 4765 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4766 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4767 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4768 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4769 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4770 orntNew[(r+0)%4] = ornt[r]; 4771 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4772 orntNew[(r+1)%4] = 0; 4773 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4774 orntNew[(r+2)%4] = -2; 4775 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4776 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4777 #if 1 4778 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4779 for (p = 0; p < 4; ++p) { 4780 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); 4781 } 4782 #endif 4783 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4784 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4785 for (s = 0; s < supportSize; ++s) { 4786 PetscInt subf; 4787 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4788 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4789 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4790 for (c = 0; c < coneSize; ++c) { 4791 if (cone[c] == f) break; 4792 } 4793 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4794 if (support[s] < cMax) { 4795 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4796 } else { 4797 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4798 } 4799 } 4800 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4801 #if 1 4802 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4803 for (p = 0; p < supportSize; ++p) { 4804 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); 4805 } 4806 #endif 4807 } 4808 } 4809 /* Interior cell faces have 4 edges and 2 cells */ 4810 for (c = cStart; c < cMax; ++c) { 4811 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}; 4812 const PetscInt *cone, *ornt; 4813 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4814 4815 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4816 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4817 /* A-D face */ 4818 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4819 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4820 orntNew[0] = 0; 4821 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4822 orntNew[1] = 0; 4823 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4824 orntNew[2] = -2; 4825 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4826 orntNew[3] = -2; 4827 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4828 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4829 #if 1 4830 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4831 for (p = 0; p < 4; ++p) { 4832 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); 4833 } 4834 #endif 4835 /* C-D face */ 4836 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4837 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4838 orntNew[0] = 0; 4839 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4840 orntNew[1] = 0; 4841 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4842 orntNew[2] = -2; 4843 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4844 orntNew[3] = -2; 4845 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4846 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4847 #if 1 4848 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4849 for (p = 0; p < 4; ++p) { 4850 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); 4851 } 4852 #endif 4853 /* B-C face */ 4854 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4855 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4856 orntNew[0] = -2; 4857 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4858 orntNew[1] = 0; 4859 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4860 orntNew[2] = 0; 4861 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4862 orntNew[3] = -2; 4863 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4864 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4865 #if 1 4866 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4867 for (p = 0; p < 4; ++p) { 4868 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); 4869 } 4870 #endif 4871 /* A-B face */ 4872 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4873 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4874 orntNew[0] = -2; 4875 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4876 orntNew[1] = 0; 4877 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4878 orntNew[2] = 0; 4879 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4880 orntNew[3] = -2; 4881 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4882 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4883 #if 1 4884 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4885 for (p = 0; p < 4; ++p) { 4886 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); 4887 } 4888 #endif 4889 /* E-F face */ 4890 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4891 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4892 orntNew[0] = -2; 4893 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4894 orntNew[1] = -2; 4895 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4896 orntNew[2] = 0; 4897 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4898 orntNew[3] = 0; 4899 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4900 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4901 #if 1 4902 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4903 for (p = 0; p < 4; ++p) { 4904 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); 4905 } 4906 #endif 4907 /* F-G face */ 4908 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4909 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4910 orntNew[0] = -2; 4911 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4912 orntNew[1] = -2; 4913 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4914 orntNew[2] = 0; 4915 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4916 orntNew[3] = 0; 4917 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4918 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4919 #if 1 4920 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4921 for (p = 0; p < 4; ++p) { 4922 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); 4923 } 4924 #endif 4925 /* G-H face */ 4926 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4927 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4928 orntNew[0] = -2; 4929 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4930 orntNew[1] = 0; 4931 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4932 orntNew[2] = 0; 4933 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4934 orntNew[3] = -2; 4935 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4936 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4937 #if 1 4938 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4939 for (p = 0; p < 4; ++p) { 4940 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); 4941 } 4942 #endif 4943 /* E-H face */ 4944 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4945 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4946 orntNew[0] = -2; 4947 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4948 orntNew[1] = -2; 4949 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4950 orntNew[2] = 0; 4951 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4952 orntNew[3] = 0; 4953 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4954 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4955 #if 1 4956 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4957 for (p = 0; p < 4; ++p) { 4958 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); 4959 } 4960 #endif 4961 /* A-E face */ 4962 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4963 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4964 orntNew[0] = 0; 4965 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4966 orntNew[1] = 0; 4967 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4968 orntNew[2] = -2; 4969 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4970 orntNew[3] = -2; 4971 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4972 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4973 #if 1 4974 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4975 for (p = 0; p < 4; ++p) { 4976 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); 4977 } 4978 #endif 4979 /* D-F face */ 4980 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4981 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4982 orntNew[0] = -2; 4983 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4984 orntNew[1] = 0; 4985 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4986 orntNew[2] = 0; 4987 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4988 orntNew[3] = -2; 4989 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4990 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4991 #if 1 4992 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4993 for (p = 0; p < 4; ++p) { 4994 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); 4995 } 4996 #endif 4997 /* C-G face */ 4998 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4999 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5000 orntNew[0] = -2; 5001 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 5002 orntNew[1] = -2; 5003 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 5004 orntNew[2] = 0; 5005 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5006 orntNew[3] = 0; 5007 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5008 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5009 #if 1 5010 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5011 for (p = 0; p < 4; ++p) { 5012 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); 5013 } 5014 #endif 5015 /* B-H face */ 5016 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 5017 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5018 orntNew[0] = 0; 5019 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5020 orntNew[1] = -2; 5021 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 5022 orntNew[2] = -2; 5023 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 5024 orntNew[3] = 0; 5025 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5026 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5027 #if 1 5028 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5029 for (p = 0; p < 4; ++p) { 5030 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); 5031 } 5032 #endif 5033 for (r = 0; r < 12; ++r) { 5034 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 5035 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 5036 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 5037 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5038 #if 1 5039 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5040 for (p = 0; p < 2; ++p) { 5041 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); 5042 } 5043 #endif 5044 } 5045 } 5046 /* Hybrid split faces have 4 edges and same cells */ 5047 for (f = fMax; f < fEnd; ++f) { 5048 const PetscInt *cone, *ornt, *support; 5049 PetscInt coneNew[4], orntNew[4]; 5050 PetscInt supportNew[2], size, s, c; 5051 5052 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5053 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5054 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5055 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5056 for (r = 0; r < 2; ++r) { 5057 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 5058 5059 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 5060 orntNew[0] = ornt[0]; 5061 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 5062 orntNew[1] = ornt[1]; 5063 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 5064 orntNew[2+r] = 0; 5065 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5066 orntNew[3-r] = 0; 5067 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5068 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5069 #if 1 5070 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 5071 for (p = 0; p < 2; ++p) { 5072 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); 5073 } 5074 for (p = 2; p < 4; ++p) { 5075 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); 5076 } 5077 #endif 5078 for (s = 0; s < size; ++s) { 5079 const PetscInt *coneCell, *orntCell, *fornt; 5080 PetscInt o, of; 5081 5082 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5083 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5084 o = orntCell[0] < 0 ? -1 : 1; 5085 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 5086 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 5087 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 5088 of = fornt[c-2] < 0 ? -1 : 1; 5089 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 5090 } 5091 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5092 #if 1 5093 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 5094 for (p = 0; p < size; ++p) { 5095 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); 5096 } 5097 #endif 5098 } 5099 } 5100 /* Hybrid cell faces have 4 edges and 2 cells */ 5101 for (c = cMax; c < cEnd; ++c) { 5102 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 5103 const PetscInt *cone, *ornt; 5104 PetscInt coneNew[4], orntNew[4]; 5105 PetscInt supportNew[2]; 5106 5107 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5108 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5109 for (r = 0; r < 4; ++r) { 5110 #if 0 5111 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 5112 orntNew[0] = 0; 5113 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 5114 orntNew[1] = 0; 5115 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 5116 orntNew[2] = 0; 5117 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5118 orntNew[3] = 0; 5119 #else 5120 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 5121 orntNew[0] = 0; 5122 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 5123 orntNew[1] = 0; 5124 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 5125 orntNew[2] = 0; 5126 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5127 orntNew[3] = 0; 5128 #endif 5129 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 5130 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 5131 #if 1 5132 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); 5133 for (p = 0; p < 2; ++p) { 5134 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); 5135 } 5136 for (p = 2; p < 4; ++p) { 5137 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); 5138 } 5139 #endif 5140 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 5141 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 5142 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 5143 #if 1 5144 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); 5145 for (p = 0; p < 2; ++p) { 5146 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); 5147 } 5148 #endif 5149 } 5150 } 5151 /* Interior split edges have 2 vertices and the same faces as the parent */ 5152 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5153 for (e = eStart; e < eMax; ++e) { 5154 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5155 5156 for (r = 0; r < 2; ++r) { 5157 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5158 const PetscInt *cone, *ornt, *support; 5159 PetscInt coneNew[2], coneSize, c, supportSize, s; 5160 5161 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5162 coneNew[0] = vStartNew + (cone[0] - vStart); 5163 coneNew[1] = vStartNew + (cone[1] - vStart); 5164 coneNew[(r+1)%2] = newv; 5165 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5166 #if 1 5167 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5168 for (p = 0; p < 2; ++p) { 5169 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); 5170 } 5171 #endif 5172 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5173 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5174 for (s = 0; s < supportSize; ++s) { 5175 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5176 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5177 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5178 for (c = 0; c < coneSize; ++c) { 5179 if (cone[c] == e) break; 5180 } 5181 if (support[s] < fMax) { 5182 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 5183 } else { 5184 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 5185 } 5186 } 5187 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5188 #if 1 5189 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5190 for (p = 0; p < supportSize; ++p) { 5191 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); 5192 } 5193 #endif 5194 } 5195 } 5196 /* Interior face edges have 2 vertices and 2+cells faces */ 5197 for (f = fStart; f < fMax; ++f) { 5198 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}; 5199 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5200 const PetscInt *cone, *coneCell, *orntCell, *support; 5201 PetscInt coneNew[2], coneSize, c, supportSize, s; 5202 5203 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5204 for (r = 0; r < 4; ++r) { 5205 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5206 5207 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5208 coneNew[1] = newv; 5209 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5210 #if 1 5211 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5212 for (p = 0; p < 2; ++p) { 5213 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); 5214 } 5215 #endif 5216 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5217 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5218 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5219 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5220 for (s = 0; s < supportSize; ++s) { 5221 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5222 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5223 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5224 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5225 if (support[s] < cMax) { 5226 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5227 } else { 5228 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 5229 } 5230 } 5231 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5232 #if 1 5233 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5234 for (p = 0; p < 2+supportSize; ++p) { 5235 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); 5236 } 5237 #endif 5238 } 5239 } 5240 /* Interior cell edges have 2 vertices and 4 faces */ 5241 for (c = cStart; c < cMax; ++c) { 5242 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}; 5243 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5244 const PetscInt *cone; 5245 PetscInt coneNew[2], supportNew[4]; 5246 5247 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5248 for (r = 0; r < 6; ++r) { 5249 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5250 5251 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5252 coneNew[1] = newv; 5253 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5254 #if 1 5255 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5256 for (p = 0; p < 2; ++p) { 5257 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); 5258 } 5259 #endif 5260 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5261 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5262 #if 1 5263 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5264 for (p = 0; p < 4; ++p) { 5265 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); 5266 } 5267 #endif 5268 } 5269 } 5270 /* Hybrid edges have two vertices and the same faces */ 5271 for (e = eMax; e < eEnd; ++e) { 5272 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5273 const PetscInt *cone, *support, *fcone; 5274 PetscInt coneNew[2], size, fsize, s; 5275 5276 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5277 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5278 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5279 coneNew[0] = vStartNew + (cone[0] - vStart); 5280 coneNew[1] = vStartNew + (cone[1] - vStart); 5281 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5282 #if 1 5283 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5284 for (p = 0; p < 2; ++p) { 5285 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); 5286 } 5287 #endif 5288 for (s = 0; s < size; ++s) { 5289 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5290 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5291 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5292 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5293 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 5294 } 5295 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5296 #if 1 5297 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5298 for (p = 0; p < size; ++p) { 5299 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); 5300 } 5301 #endif 5302 } 5303 /* Hybrid face edges have 2 vertices and 2+cells faces */ 5304 for (f = fMax; f < fEnd; ++f) { 5305 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5306 const PetscInt *cone, *support, *ccone, *cornt; 5307 PetscInt coneNew[2], size, csize, s; 5308 5309 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5310 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5311 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5312 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5313 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 5314 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5315 #if 1 5316 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5317 for (p = 0; p < 2; ++p) { 5318 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); 5319 } 5320 #endif 5321 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 5322 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5323 for (s = 0; s < size; ++s) { 5324 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5325 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5326 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5327 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5328 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]); 5329 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 5330 } 5331 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5332 #if 1 5333 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5334 for (p = 0; p < 2+size; ++p) { 5335 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); 5336 } 5337 #endif 5338 } 5339 /* Hybrid cell edges have 2 vertices and 4 faces */ 5340 for (c = cMax; c < cEnd; ++c) { 5341 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5342 const PetscInt *cone, *support; 5343 PetscInt coneNew[2], size; 5344 5345 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5346 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5347 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5348 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5349 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5350 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5351 #if 1 5352 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5353 for (p = 0; p < 2; ++p) { 5354 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); 5355 } 5356 #endif 5357 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5358 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5359 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5360 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5361 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5362 #if 1 5363 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5364 for (p = 0; p < 4; ++p) { 5365 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); 5366 } 5367 #endif 5368 } 5369 /* Interior vertices have identical supports */ 5370 for (v = vStart; v < vEnd; ++v) { 5371 const PetscInt newp = vStartNew + (v - vStart); 5372 const PetscInt *support, *cone; 5373 PetscInt size, s; 5374 5375 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5376 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5377 for (s = 0; s < size; ++s) { 5378 PetscInt r = 0; 5379 5380 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5381 if (cone[1] == v) r = 1; 5382 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5383 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5384 } 5385 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5386 #if 1 5387 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5388 for (p = 0; p < size; ++p) { 5389 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); 5390 } 5391 #endif 5392 } 5393 /* Interior edge vertices have 2 + faces supports */ 5394 for (e = eStart; e < eMax; ++e) { 5395 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5396 const PetscInt *cone, *support; 5397 PetscInt size, s; 5398 5399 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5400 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5401 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5402 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5403 for (s = 0; s < size; ++s) { 5404 PetscInt r; 5405 5406 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5407 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5408 if (support[s] < fMax) { 5409 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5410 } else { 5411 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5412 } 5413 } 5414 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5415 #if 1 5416 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5417 for (p = 0; p < 2+size; ++p) { 5418 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); 5419 } 5420 #endif 5421 } 5422 /* Interior face vertices have 4 + cells supports */ 5423 for (f = fStart; f < fMax; ++f) { 5424 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5425 const PetscInt *cone, *support; 5426 PetscInt size, s; 5427 5428 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5429 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5430 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5431 for (s = 0; s < size; ++s) { 5432 PetscInt r; 5433 5434 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5435 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5436 if (support[s] < cMax) { 5437 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5438 } else { 5439 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5440 } 5441 } 5442 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5443 #if 1 5444 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5445 for (p = 0; p < 4+size; ++p) { 5446 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); 5447 } 5448 #endif 5449 } 5450 /* Cell vertices have 6 supports */ 5451 for (c = cStart; c < cMax; ++c) { 5452 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5453 PetscInt supportNew[6]; 5454 5455 for (r = 0; r < 6; ++r) { 5456 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5457 } 5458 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5459 } 5460 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5461 break; 5462 default: 5463 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5464 } 5465 PetscFunctionReturn(0); 5466 } 5467 5468 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5469 { 5470 PetscSection coordSection, coordSectionNew; 5471 Vec coordinates, coordinatesNew; 5472 PetscScalar *coords, *coordsNew; 5473 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5474 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5475 VecType vtype; 5476 PetscErrorCode ierr; 5477 5478 PetscFunctionBegin; 5479 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5480 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5481 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5482 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5483 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5484 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5485 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5486 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5487 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5488 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5489 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 5490 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5491 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5492 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 5493 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5494 if (cMax < 0) cMax = cEnd; 5495 if (fMax < 0) fMax = fEnd; 5496 if (eMax < 0) eMax = eEnd; 5497 /* All vertices have the spaceDim coordinates */ 5498 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5499 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 5500 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 5501 } 5502 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5503 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 5504 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5505 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5506 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 5507 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5508 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5509 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 5510 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 5511 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 5512 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 5513 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5514 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5515 switch (refiner) { 5516 case REFINER_NOOP: break; 5517 case REFINER_HEX_3D: 5518 case REFINER_HYBRID_HEX_3D: 5519 /* Face vertices have the average of corner coordinates */ 5520 for (f = fStart; f < fMax; ++f) { 5521 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5522 PetscInt *cone = NULL; 5523 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5524 5525 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5526 for (p = 0; p < closureSize*2; p += 2) { 5527 const PetscInt point = cone[p]; 5528 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5529 } 5530 for (v = 0; v < coneSize; ++v) { 5531 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5532 } 5533 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5534 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5535 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5536 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5537 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5538 } 5539 case REFINER_HEX_2D: 5540 case REFINER_HYBRID_HEX_2D: 5541 case REFINER_SIMPLEX_1D: 5542 /* Cell vertices have the average of corner coordinates */ 5543 for (c = cStart; c < cMax; ++c) { 5544 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 5545 PetscInt *cone = NULL; 5546 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5547 5548 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5549 for (p = 0; p < closureSize*2; p += 2) { 5550 const PetscInt point = cone[p]; 5551 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5552 } 5553 for (v = 0; v < coneSize; ++v) { 5554 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5555 } 5556 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5557 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5558 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5559 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5560 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5561 } 5562 case REFINER_SIMPLEX_2D: 5563 case REFINER_HYBRID_SIMPLEX_2D: 5564 case REFINER_SIMPLEX_3D: 5565 case REFINER_HYBRID_SIMPLEX_3D: 5566 /* Edge vertices have the average of endpoint coordinates */ 5567 for (e = eStart; e < eMax; ++e) { 5568 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5569 const PetscInt *cone; 5570 PetscInt coneSize, offA, offB, offnew, d; 5571 5572 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5573 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5574 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5575 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5576 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5577 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5578 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 5579 for (d = 0; d < spaceDim; ++d) { 5580 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 5581 } 5582 } 5583 /* Old vertices have the same coordinates */ 5584 for (v = vStart; v < vEnd; ++v) { 5585 const PetscInt newv = vStartNew + (v - vStart); 5586 PetscInt off, offnew, d; 5587 5588 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5589 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5590 for (d = 0; d < spaceDim; ++d) { 5591 coordsNew[offnew+d] = coords[off+d]; 5592 } 5593 } 5594 break; 5595 default: 5596 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5597 } 5598 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5599 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5600 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5601 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5602 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5603 if (dm->maxCell) { 5604 const PetscReal *maxCell, *L; 5605 const DMBoundaryType *bd; 5606 ierr = DMGetPeriodicity(dm, &maxCell, &L, &bd);CHKERRQ(ierr); 5607 ierr = DMSetPeriodicity(rdm, maxCell, L, bd);CHKERRQ(ierr); 5608 } 5609 PetscFunctionReturn(0); 5610 } 5611 5612 /*@ 5613 DMPlexCreateProcessSF - Create an SF which just has process connectivity 5614 5615 Collective on DM 5616 5617 Input Parameters: 5618 + dm - The DM 5619 - sfPoint - The PetscSF which encodes point connectivity 5620 5621 Output Parameters: 5622 + processRanks - A list of process neighbors, or NULL 5623 - sfProcess - An SF encoding the process connectivity, or NULL 5624 5625 Level: developer 5626 5627 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 5628 @*/ 5629 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5630 { 5631 PetscInt numRoots, numLeaves, l; 5632 const PetscInt *localPoints; 5633 const PetscSFNode *remotePoints; 5634 PetscInt *localPointsNew; 5635 PetscSFNode *remotePointsNew; 5636 PetscInt *ranks, *ranksNew; 5637 PetscMPIInt size; 5638 PetscErrorCode ierr; 5639 5640 PetscFunctionBegin; 5641 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5642 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 5643 if (processRanks) {PetscValidPointer(processRanks, 3);} 5644 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 5645 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 5646 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5647 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5648 for (l = 0; l < numLeaves; ++l) { 5649 ranks[l] = remotePoints[l].rank; 5650 } 5651 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5652 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5653 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5654 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5655 for (l = 0; l < numLeaves; ++l) { 5656 ranksNew[l] = ranks[l]; 5657 localPointsNew[l] = l; 5658 remotePointsNew[l].index = 0; 5659 remotePointsNew[l].rank = ranksNew[l]; 5660 } 5661 ierr = PetscFree(ranks);CHKERRQ(ierr); 5662 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 5663 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 5664 if (sfProcess) { 5665 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5666 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 5667 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5668 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5669 } 5670 PetscFunctionReturn(0); 5671 } 5672 5673 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5674 { 5675 PetscSF sf, sfNew, sfProcess; 5676 IS processRanks; 5677 MPI_Datatype depthType; 5678 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5679 const PetscInt *localPoints, *neighbors; 5680 const PetscSFNode *remotePoints; 5681 PetscInt *localPointsNew; 5682 PetscSFNode *remotePointsNew; 5683 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5684 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5685 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5686 PetscErrorCode ierr; 5687 5688 PetscFunctionBegin; 5689 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5690 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 5691 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 5692 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth); 5693 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5694 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5695 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5696 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5697 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5698 cMax = cMax < 0 ? cEnd : cMax; 5699 fMax = fMax < 0 ? fEnd : fMax; 5700 eMax = eMax < 0 ? eEnd : eMax; 5701 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5702 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5703 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5704 /* Calculate size of new SF */ 5705 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5706 if (numRoots < 0) PetscFunctionReturn(0); 5707 for (l = 0; l < numLeaves; ++l) { 5708 const PetscInt p = localPoints[l]; 5709 5710 switch (refiner) { 5711 case REFINER_SIMPLEX_1D: 5712 if ((p >= vStart) && (p < vEnd)) { 5713 /* Interior vertices stay the same */ 5714 ++numLeavesNew; 5715 } else if ((p >= cStart && p < cMax)) { 5716 /* Interior cells add new cells and interior vertices */ 5717 numLeavesNew += 2 + 1; 5718 } 5719 break; 5720 case REFINER_SIMPLEX_2D: 5721 case REFINER_HYBRID_SIMPLEX_2D: 5722 if ((p >= vStart) && (p < vEnd)) { 5723 /* Interior vertices stay the same */ 5724 ++numLeavesNew; 5725 } else if ((p >= fStart) && (p < fMax)) { 5726 /* Interior faces add new faces and vertex */ 5727 numLeavesNew += 2 + 1; 5728 } else if ((p >= fMax) && (p < fEnd)) { 5729 /* Hybrid faces stay the same */ 5730 ++numLeavesNew; 5731 } else if ((p >= cStart) && (p < cMax)) { 5732 /* Interior cells add new cells and interior faces */ 5733 numLeavesNew += 4 + 3; 5734 } else if ((p >= cMax) && (p < cEnd)) { 5735 /* Hybrid cells add new cells and hybrid face */ 5736 numLeavesNew += 2 + 1; 5737 } 5738 break; 5739 case REFINER_HEX_2D: 5740 case REFINER_HYBRID_HEX_2D: 5741 if ((p >= vStart) && (p < vEnd)) { 5742 /* Interior vertices stay the same */ 5743 ++numLeavesNew; 5744 } else if ((p >= fStart) && (p < fMax)) { 5745 /* Interior faces add new faces and vertex */ 5746 numLeavesNew += 2 + 1; 5747 } else if ((p >= fMax) && (p < fEnd)) { 5748 /* Hybrid faces stay the same */ 5749 ++numLeavesNew; 5750 } else if ((p >= cStart) && (p < cMax)) { 5751 /* Interior cells add new cells, interior faces, and vertex */ 5752 numLeavesNew += 4 + 4 + 1; 5753 } else if ((p >= cMax) && (p < cEnd)) { 5754 /* Hybrid cells add new cells and hybrid face */ 5755 numLeavesNew += 2 + 1; 5756 } 5757 break; 5758 case REFINER_SIMPLEX_3D: 5759 case REFINER_HYBRID_SIMPLEX_3D: 5760 if ((p >= vStart) && (p < vEnd)) { 5761 /* Interior vertices stay the same */ 5762 ++numLeavesNew; 5763 } else if ((p >= eStart) && (p < eMax)) { 5764 /* Interior edges add new edges and vertex */ 5765 numLeavesNew += 2 + 1; 5766 } else if ((p >= eMax) && (p < eEnd)) { 5767 /* Hybrid edges stay the same */ 5768 ++numLeavesNew; 5769 } else if ((p >= fStart) && (p < fMax)) { 5770 /* Interior faces add new faces and edges */ 5771 numLeavesNew += 4 + 3; 5772 } else if ((p >= fMax) && (p < fEnd)) { 5773 /* Hybrid faces add new faces and edges */ 5774 numLeavesNew += 2 + 1; 5775 } else if ((p >= cStart) && (p < cMax)) { 5776 /* Interior cells add new cells, faces, and edges */ 5777 numLeavesNew += 8 + 8 + 1; 5778 } else if ((p >= cMax) && (p < cEnd)) { 5779 /* Hybrid cells add new cells and faces */ 5780 numLeavesNew += 4 + 3; 5781 } 5782 break; 5783 case REFINER_HEX_3D: 5784 case REFINER_HYBRID_HEX_3D: 5785 if ((p >= vStart) && (p < vEnd)) { 5786 /* Old vertices stay the same */ 5787 ++numLeavesNew; 5788 } else if ((p >= eStart) && (p < eMax)) { 5789 /* Interior edges add new edges, and vertex */ 5790 numLeavesNew += 2 + 1; 5791 } else if ((p >= eMax) && (p < eEnd)) { 5792 /* Hybrid edges stay the same */ 5793 ++numLeavesNew; 5794 } else if ((p >= fStart) && (p < fMax)) { 5795 /* Interior faces add new faces, edges, and vertex */ 5796 numLeavesNew += 4 + 4 + 1; 5797 } else if ((p >= fMax) && (p < fEnd)) { 5798 /* Hybrid faces add new faces and edges */ 5799 numLeavesNew += 2 + 1; 5800 } else if ((p >= cStart) && (p < cMax)) { 5801 /* Interior cells add new cells, faces, edges, and vertex */ 5802 numLeavesNew += 8 + 12 + 6 + 1; 5803 } else if ((p >= cStart) && (p < cEnd)) { 5804 /* Hybrid cells add new cells, faces, and edges */ 5805 numLeavesNew += 4 + 4 + 1; 5806 } 5807 break; 5808 default: 5809 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5810 } 5811 } 5812 /* Communicate depthSizes for each remote rank */ 5813 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5814 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5815 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5816 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5817 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5818 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5819 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5820 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5821 for (n = 0; n < numNeighbors; ++n) { 5822 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5823 } 5824 depthSizeOld[depth] = cMax; 5825 depthSizeOld[0] = vMax; 5826 depthSizeOld[depth-1] = fMax; 5827 depthSizeOld[1] = eMax; 5828 5829 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5830 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5831 5832 depthSizeOld[depth] = cEnd - cStart; 5833 depthSizeOld[0] = vEnd - vStart; 5834 depthSizeOld[depth-1] = fEnd - fStart; 5835 depthSizeOld[1] = eEnd - eStart; 5836 5837 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5838 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5839 for (n = 0; n < numNeighbors; ++n) { 5840 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5841 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 5842 rdepthMaxOld[n*(depth+1)+depth-1] = rdepthMaxOld[n*(depth+1)+depth-1] < 0 ? rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n]: rdepthMaxOld[n*(depth+1)+depth-1]; 5843 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 5844 } 5845 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5846 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5847 /* Calculate new point SF */ 5848 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5849 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5850 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5851 for (l = 0, m = 0; l < numLeaves; ++l) { 5852 PetscInt p = localPoints[l]; 5853 PetscInt rp = remotePoints[l].index, n; 5854 PetscMPIInt rrank = remotePoints[l].rank; 5855 5856 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5857 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5858 switch (refiner) { 5859 case REFINER_SIMPLEX_1D: 5860 if ((p >= vStart) && (p < vEnd)) { 5861 /* Old vertices stay the same */ 5862 localPointsNew[m] = vStartNew + (p - vStart); 5863 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5864 remotePointsNew[m].rank = rrank; 5865 ++m; 5866 } else if ((p >= cStart) && (p < cMax)) { 5867 /* Old interior cells add new cells and vertex */ 5868 for (r = 0; r < 2; ++r, ++m) { 5869 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 5870 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 5871 remotePointsNew[m].rank = rrank; 5872 } 5873 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 5874 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 5875 remotePointsNew[m].rank = rrank; 5876 ++m; 5877 } 5878 break; 5879 case REFINER_SIMPLEX_2D: 5880 case REFINER_HYBRID_SIMPLEX_2D: 5881 if ((p >= vStart) && (p < vEnd)) { 5882 /* Old vertices stay the same */ 5883 localPointsNew[m] = vStartNew + (p - vStart); 5884 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5885 remotePointsNew[m].rank = rrank; 5886 ++m; 5887 } else if ((p >= fStart) && (p < fMax)) { 5888 /* Old interior faces add new faces and vertex */ 5889 for (r = 0; r < 2; ++r, ++m) { 5890 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5891 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5892 remotePointsNew[m].rank = rrank; 5893 } 5894 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5895 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5896 remotePointsNew[m].rank = rrank; 5897 ++m; 5898 } else if ((p >= fMax) && (p < fEnd)) { 5899 /* Old hybrid faces stay the same */ 5900 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5901 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5902 remotePointsNew[m].rank = rrank; 5903 ++m; 5904 } else if ((p >= cStart) && (p < cMax)) { 5905 /* Old interior cells add new cells and interior faces */ 5906 for (r = 0; r < 4; ++r, ++m) { 5907 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5908 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5909 remotePointsNew[m].rank = rrank; 5910 } 5911 for (r = 0; r < 3; ++r, ++m) { 5912 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5913 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5914 remotePointsNew[m].rank = rrank; 5915 } 5916 } else if ((p >= cMax) && (p < cEnd)) { 5917 /* Old hybrid cells add new cells and hybrid face */ 5918 for (r = 0; r < 2; ++r, ++m) { 5919 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5920 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5921 remotePointsNew[m].rank = rrank; 5922 } 5923 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5924 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]); 5925 remotePointsNew[m].rank = rrank; 5926 ++m; 5927 } 5928 break; 5929 case REFINER_HEX_2D: 5930 case REFINER_HYBRID_HEX_2D: 5931 if ((p >= vStart) && (p < vEnd)) { 5932 /* Old vertices stay the same */ 5933 localPointsNew[m] = vStartNew + (p - vStart); 5934 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5935 remotePointsNew[m].rank = rrank; 5936 ++m; 5937 } else if ((p >= fStart) && (p < fMax)) { 5938 /* Old interior faces add new faces and vertex */ 5939 for (r = 0; r < 2; ++r, ++m) { 5940 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5941 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5942 remotePointsNew[m].rank = rrank; 5943 } 5944 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5945 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5946 remotePointsNew[m].rank = rrank; 5947 ++m; 5948 } else if ((p >= fMax) && (p < fEnd)) { 5949 /* Old hybrid faces stay the same */ 5950 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5951 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5952 remotePointsNew[m].rank = rrank; 5953 ++m; 5954 } else if ((p >= cStart) && (p < cMax)) { 5955 /* Old interior cells add new cells, interior faces, and vertex */ 5956 for (r = 0; r < 4; ++r, ++m) { 5957 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5958 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5959 remotePointsNew[m].rank = rrank; 5960 } 5961 for (r = 0; r < 4; ++r, ++m) { 5962 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5963 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5964 remotePointsNew[m].rank = rrank; 5965 } 5966 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 5967 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 5968 remotePointsNew[m].rank = rrank; 5969 ++m; 5970 } else if ((p >= cStart) && (p < cMax)) { 5971 /* Old hybrid cells add new cells and hybrid face */ 5972 for (r = 0; r < 2; ++r, ++m) { 5973 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5974 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5975 remotePointsNew[m].rank = rrank; 5976 } 5977 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5978 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]); 5979 remotePointsNew[m].rank = rrank; 5980 ++m; 5981 } 5982 break; 5983 case REFINER_SIMPLEX_3D: 5984 case REFINER_HYBRID_SIMPLEX_3D: 5985 if ((p >= vStart) && (p < vEnd)) { 5986 /* Interior vertices stay the same */ 5987 localPointsNew[m] = vStartNew + (p - vStart); 5988 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5989 remotePointsNew[m].rank = rrank; 5990 ++m; 5991 } else if ((p >= eStart) && (p < eMax)) { 5992 /* Interior edges add new edges and vertex */ 5993 for (r = 0; r < 2; ++r, ++m) { 5994 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5995 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5996 remotePointsNew[m].rank = rrank; 5997 } 5998 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5999 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6000 remotePointsNew[m].rank = rrank; 6001 ++m; 6002 } else if ((p >= eMax) && (p < eEnd)) { 6003 /* Hybrid edges stay the same */ 6004 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6005 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]); 6006 remotePointsNew[m].rank = rrank; 6007 ++m; 6008 } else if ((p >= fStart) && (p < fMax)) { 6009 /* Interior faces add new faces and edges */ 6010 for (r = 0; r < 4; ++r, ++m) { 6011 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6012 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6013 remotePointsNew[m].rank = rrank; 6014 } 6015 for (r = 0; r < 3; ++r, ++m) { 6016 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6017 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 6018 remotePointsNew[m].rank = rrank; 6019 } 6020 } else if ((p >= fMax) && (p < fEnd)) { 6021 /* Hybrid faces add new faces and edges */ 6022 for (r = 0; r < 2; ++r, ++m) { 6023 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6024 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; 6025 remotePointsNew[m].rank = rrank; 6026 } 6027 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 6028 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]); 6029 remotePointsNew[m].rank = rrank; 6030 ++m; 6031 } else if ((p >= cStart) && (p < cMax)) { 6032 /* Interior cells add new cells, faces, and edges */ 6033 for (r = 0; r < 8; ++r, ++m) { 6034 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6035 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6036 remotePointsNew[m].rank = rrank; 6037 } 6038 for (r = 0; r < 8; ++r, ++m) { 6039 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6040 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 6041 remotePointsNew[m].rank = rrank; 6042 } 6043 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 6044 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*3 + (rp - rcStart[n])*1 + 0; 6045 remotePointsNew[m].rank = rrank; 6046 ++m; 6047 } else if ((p >= cMax) && (p < cEnd)) { 6048 /* Hybrid cells add new cells and faces */ 6049 for (r = 0; r < 4; ++r, ++m) { 6050 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6051 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6052 remotePointsNew[m].rank = rrank; 6053 } 6054 for (r = 0; r < 3; ++r, ++m) { 6055 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6056 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; 6057 remotePointsNew[m].rank = rrank; 6058 } 6059 } 6060 break; 6061 case REFINER_HEX_3D: 6062 case REFINER_HYBRID_HEX_3D: 6063 if ((p >= vStart) && (p < vEnd)) { 6064 /* Interior vertices stay the same */ 6065 localPointsNew[m] = vStartNew + (p - vStart); 6066 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6067 remotePointsNew[m].rank = rrank; 6068 ++m; 6069 } else if ((p >= eStart) && (p < eMax)) { 6070 /* Interior edges add new edges and vertex */ 6071 for (r = 0; r < 2; ++r, ++m) { 6072 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6073 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6074 remotePointsNew[m].rank = rrank; 6075 } 6076 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6077 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6078 remotePointsNew[m].rank = rrank; 6079 ++m; 6080 } else if ((p >= eMax) && (p < eEnd)) { 6081 /* Hybrid edges stay the same */ 6082 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6083 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+1]); 6084 remotePointsNew[m].rank = rrank; 6085 ++m; 6086 } else if ((p >= fStart) && (p < fMax)) { 6087 /* Interior faces add new faces, edges, and vertex */ 6088 for (r = 0; r < 4; ++r, ++m) { 6089 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6090 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6091 remotePointsNew[m].rank = rrank; 6092 } 6093 for (r = 0; r < 4; ++r, ++m) { 6094 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6095 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 6096 remotePointsNew[m].rank = rrank; 6097 } 6098 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6099 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 6100 remotePointsNew[m].rank = rrank; 6101 ++m; 6102 } else if ((p >= fMax) && (p < fEnd)) { 6103 /* Hybrid faces add new faces and edges */ 6104 for (r = 0; r < 2; ++r, ++m) { 6105 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6106 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 6107 remotePointsNew[m].rank = rrank; 6108 } 6109 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 6110 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 6111 remotePointsNew[m].rank = rrank; 6112 ++m; 6113 } else if ((p >= cStart) && (p < cMax)) { 6114 /* Interior cells add new cells, faces, edges, and vertex */ 6115 for (r = 0; r < 8; ++r, ++m) { 6116 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6117 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6118 remotePointsNew[m].rank = rrank; 6119 } 6120 for (r = 0; r < 12; ++r, ++m) { 6121 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6122 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6123 remotePointsNew[m].rank = rrank; 6124 } 6125 for (r = 0; r < 6; ++r, ++m) { 6126 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6127 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; 6128 remotePointsNew[m].rank = rrank; 6129 } 6130 for (r = 0; r < 1; ++r, ++m) { 6131 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6132 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6133 remotePointsNew[m].rank = rrank; 6134 } 6135 } else if ((p >= cMax) && (p < cEnd)) { 6136 /* Hybrid cells add new cells, faces, and edges */ 6137 for (r = 0; r < 4; ++r, ++m) { 6138 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6139 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6140 remotePointsNew[m].rank = rrank; 6141 } 6142 for (r = 0; r < 4; ++r, ++m) { 6143 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6144 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*12 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6145 remotePointsNew[m].rank = rrank; 6146 } 6147 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 6148 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1]) + (rp - rdepthMaxOld[n*(depth+1)+depth]); 6149 remotePointsNew[m].rank = rrank; 6150 ++m; 6151 } 6152 break; 6153 default: 6154 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6155 } 6156 } 6157 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6158 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6159 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6160 { 6161 PetscSFNode *rp, *rtmp; 6162 PetscInt *lp, *idx, *ltmp, i; 6163 6164 /* SF needs sorted leaves to correct calculate Gather */ 6165 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 6166 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 6167 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 6168 for (i = 0; i < numLeavesNew; ++i) { 6169 if ((localPointsNew[i] < pStartNew) || (localPointsNew[i] >= pEndNew)) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Local SF point %d (%d) not in [%d, %d)", localPointsNew[i], i, pStartNew, pEndNew); 6170 idx[i] = i; 6171 } 6172 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 6173 for (i = 0; i < numLeavesNew; ++i) { 6174 lp[i] = localPointsNew[idx[i]]; 6175 rp[i] = remotePointsNew[idx[i]]; 6176 } 6177 ltmp = localPointsNew; 6178 localPointsNew = lp; 6179 rtmp = remotePointsNew; 6180 remotePointsNew = rp; 6181 ierr = PetscFree(idx);CHKERRQ(ierr); 6182 ierr = PetscFree(ltmp);CHKERRQ(ierr); 6183 ierr = PetscFree(rtmp);CHKERRQ(ierr); 6184 } 6185 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6186 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6187 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6188 PetscFunctionReturn(0); 6189 } 6190 6191 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6192 { 6193 PetscInt numLabels, l; 6194 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6195 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6196 PetscErrorCode ierr; 6197 6198 PetscFunctionBegin; 6199 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6200 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6201 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6202 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6203 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6204 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6205 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6206 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6207 switch (refiner) { 6208 case REFINER_NOOP: 6209 case REFINER_SIMPLEX_1D: 6210 case REFINER_SIMPLEX_2D: 6211 case REFINER_HEX_2D: 6212 case REFINER_SIMPLEX_3D: 6213 case REFINER_HEX_3D: 6214 break; 6215 case REFINER_HYBRID_SIMPLEX_3D: 6216 case REFINER_HYBRID_HEX_3D: 6217 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6218 case REFINER_HYBRID_SIMPLEX_2D: 6219 case REFINER_HYBRID_HEX_2D: 6220 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6221 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6222 break; 6223 default: 6224 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6225 } 6226 for (l = 0; l < numLabels; ++l) { 6227 DMLabel label, labelNew; 6228 const char *lname; 6229 PetscBool isDepth; 6230 IS valueIS; 6231 const PetscInt *values; 6232 PetscInt defVal; 6233 PetscInt numValues, val; 6234 6235 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6236 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6237 if (isDepth) continue; 6238 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 6239 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 6240 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6241 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 6242 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 6243 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6244 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6245 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6246 for (val = 0; val < numValues; ++val) { 6247 IS pointIS; 6248 const PetscInt *points; 6249 PetscInt numPoints, n; 6250 6251 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6252 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6253 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6254 /* Ensure refined label is created with same number of strata as 6255 * original (even if no entries here). */ 6256 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 6257 for (n = 0; n < numPoints; ++n) { 6258 const PetscInt p = points[n]; 6259 switch (refiner) { 6260 case REFINER_SIMPLEX_1D: 6261 if ((p >= vStart) && (p < vEnd)) { 6262 /* Old vertices stay the same */ 6263 newp = vStartNew + (p - vStart); 6264 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6265 } else if ((p >= cStart) && (p < cEnd)) { 6266 /* Old cells add new cells and vertex */ 6267 newp = vStartNew + (vEnd - vStart) + (p - cStart); 6268 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6269 for (r = 0; r < 2; ++r) { 6270 newp = cStartNew + (p - cStart)*2 + r; 6271 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6272 } 6273 } 6274 break; 6275 case REFINER_SIMPLEX_2D: 6276 if ((p >= vStart) && (p < vEnd)) { 6277 /* Old vertices stay the same */ 6278 newp = vStartNew + (p - vStart); 6279 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6280 } else if ((p >= fStart) && (p < fEnd)) { 6281 /* Old faces add new faces and vertex */ 6282 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6283 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6284 for (r = 0; r < 2; ++r) { 6285 newp = fStartNew + (p - fStart)*2 + r; 6286 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6287 } 6288 } else if ((p >= cStart) && (p < cEnd)) { 6289 /* Old cells add new cells and interior faces */ 6290 for (r = 0; r < 4; ++r) { 6291 newp = cStartNew + (p - cStart)*4 + r; 6292 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6293 } 6294 for (r = 0; r < 3; ++r) { 6295 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6296 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6297 } 6298 } 6299 break; 6300 case REFINER_HEX_2D: 6301 if ((p >= vStart) && (p < vEnd)) { 6302 /* Old vertices stay the same */ 6303 newp = vStartNew + (p - vStart); 6304 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6305 } else if ((p >= fStart) && (p < fEnd)) { 6306 /* Old faces add new faces and vertex */ 6307 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6308 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6309 for (r = 0; r < 2; ++r) { 6310 newp = fStartNew + (p - fStart)*2 + r; 6311 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6312 } 6313 } else if ((p >= cStart) && (p < cEnd)) { 6314 /* Old cells add new cells and interior faces and vertex */ 6315 for (r = 0; r < 4; ++r) { 6316 newp = cStartNew + (p - cStart)*4 + r; 6317 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6318 } 6319 for (r = 0; r < 4; ++r) { 6320 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6321 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6322 } 6323 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6324 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6325 } 6326 break; 6327 case REFINER_HYBRID_SIMPLEX_2D: 6328 if ((p >= vStart) && (p < vEnd)) { 6329 /* Old vertices stay the same */ 6330 newp = vStartNew + (p - vStart); 6331 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6332 } else if ((p >= fStart) && (p < fMax)) { 6333 /* Old interior faces add new faces and vertex */ 6334 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6335 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6336 for (r = 0; r < 2; ++r) { 6337 newp = fStartNew + (p - fStart)*2 + r; 6338 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6339 } 6340 } else if ((p >= fMax) && (p < fEnd)) { 6341 /* Old hybrid faces stay the same */ 6342 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6343 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6344 } else if ((p >= cStart) && (p < cMax)) { 6345 /* Old interior cells add new cells and interior faces */ 6346 for (r = 0; r < 4; ++r) { 6347 newp = cStartNew + (p - cStart)*4 + r; 6348 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6349 } 6350 for (r = 0; r < 3; ++r) { 6351 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6352 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6353 } 6354 } else if ((p >= cMax) && (p < cEnd)) { 6355 /* Old hybrid cells add new cells and hybrid face */ 6356 for (r = 0; r < 2; ++r) { 6357 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6358 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6359 } 6360 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6361 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6362 } 6363 break; 6364 case REFINER_HYBRID_HEX_2D: 6365 if ((p >= vStart) && (p < vEnd)) { 6366 /* Old vertices stay the same */ 6367 newp = vStartNew + (p - vStart); 6368 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6369 } else if ((p >= fStart) && (p < fMax)) { 6370 /* Old interior faces add new faces and vertex */ 6371 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6372 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6373 for (r = 0; r < 2; ++r) { 6374 newp = fStartNew + (p - fStart)*2 + r; 6375 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6376 } 6377 } else if ((p >= fMax) && (p < fEnd)) { 6378 /* Old hybrid faces stay the same */ 6379 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6380 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6381 } else if ((p >= cStart) && (p < cMax)) { 6382 /* Old interior cells add new cells, interior faces, and vertex */ 6383 for (r = 0; r < 4; ++r) { 6384 newp = cStartNew + (p - cStart)*4 + r; 6385 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6386 } 6387 for (r = 0; r < 4; ++r) { 6388 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6389 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6390 } 6391 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6392 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6393 } else if ((p >= cMax) && (p < cEnd)) { 6394 /* Old hybrid cells add new cells and hybrid face */ 6395 for (r = 0; r < 2; ++r) { 6396 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6397 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6398 } 6399 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6400 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6401 } 6402 break; 6403 case REFINER_SIMPLEX_3D: 6404 if ((p >= vStart) && (p < vEnd)) { 6405 /* Old vertices stay the same */ 6406 newp = vStartNew + (p - vStart); 6407 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6408 } else if ((p >= eStart) && (p < eEnd)) { 6409 /* Old edges add new edges and vertex */ 6410 for (r = 0; r < 2; ++r) { 6411 newp = eStartNew + (p - eStart)*2 + r; 6412 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6413 } 6414 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6415 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6416 } else if ((p >= fStart) && (p < fEnd)) { 6417 /* Old faces add new faces and edges */ 6418 for (r = 0; r < 4; ++r) { 6419 newp = fStartNew + (p - fStart)*4 + r; 6420 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6421 } 6422 for (r = 0; r < 3; ++r) { 6423 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6424 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6425 } 6426 } else if ((p >= cStart) && (p < cEnd)) { 6427 /* Old cells add new cells and interior faces and edges */ 6428 for (r = 0; r < 8; ++r) { 6429 newp = cStartNew + (p - cStart)*8 + r; 6430 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6431 } 6432 for (r = 0; r < 8; ++r) { 6433 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6434 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6435 } 6436 for (r = 0; r < 1; ++r) { 6437 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6438 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6439 } 6440 } 6441 break; 6442 case REFINER_HYBRID_SIMPLEX_3D: 6443 if ((p >= vStart) && (p < vEnd)) { 6444 /* Interior vertices stay the same */ 6445 newp = vStartNew + (p - vStart); 6446 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6447 } else if ((p >= eStart) && (p < eMax)) { 6448 /* Interior edges add new edges and vertex */ 6449 for (r = 0; r < 2; ++r) { 6450 newp = eStartNew + (p - eStart)*2 + r; 6451 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6452 } 6453 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6454 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6455 } else if ((p >= eMax) && (p < eEnd)) { 6456 /* Hybrid edges stay the same */ 6457 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6458 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6459 } else if ((p >= fStart) && (p < fMax)) { 6460 /* Interior faces add new faces and edges */ 6461 for (r = 0; r < 4; ++r) { 6462 newp = fStartNew + (p - fStart)*4 + r; 6463 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6464 } 6465 for (r = 0; r < 3; ++r) { 6466 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6467 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6468 } 6469 } else if ((p >= fMax) && (p < fEnd)) { 6470 /* Hybrid faces add new faces and edges */ 6471 for (r = 0; r < 2; ++r) { 6472 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6473 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6474 } 6475 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6476 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6477 } else if ((p >= cStart) && (p < cMax)) { 6478 /* Interior cells add new cells, faces, and edges */ 6479 for (r = 0; r < 8; ++r) { 6480 newp = cStartNew + (p - cStart)*8 + r; 6481 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6482 } 6483 for (r = 0; r < 8; ++r) { 6484 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6485 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6486 } 6487 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6488 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6489 } else if ((p >= cMax) && (p < cEnd)) { 6490 /* Hybrid cells add new cells and faces */ 6491 for (r = 0; r < 4; ++r) { 6492 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6493 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6494 } 6495 for (r = 0; r < 3; ++r) { 6496 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6497 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6498 } 6499 } 6500 break; 6501 case REFINER_HEX_3D: 6502 if ((p >= vStart) && (p < vEnd)) { 6503 /* Old vertices stay the same */ 6504 newp = vStartNew + (p - vStart); 6505 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6506 } else if ((p >= eStart) && (p < eEnd)) { 6507 /* Old edges add new edges and vertex */ 6508 for (r = 0; r < 2; ++r) { 6509 newp = eStartNew + (p - eStart)*2 + r; 6510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6511 } 6512 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6513 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6514 } else if ((p >= fStart) && (p < fEnd)) { 6515 /* Old faces add new faces, edges, and vertex */ 6516 for (r = 0; r < 4; ++r) { 6517 newp = fStartNew + (p - fStart)*4 + r; 6518 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6519 } 6520 for (r = 0; r < 4; ++r) { 6521 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6522 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6523 } 6524 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6525 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6526 } else if ((p >= cStart) && (p < cEnd)) { 6527 /* Old cells add new cells, faces, edges, and vertex */ 6528 for (r = 0; r < 8; ++r) { 6529 newp = cStartNew + (p - cStart)*8 + r; 6530 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6531 } 6532 for (r = 0; r < 12; ++r) { 6533 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6534 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6535 } 6536 for (r = 0; r < 6; ++r) { 6537 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6538 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6539 } 6540 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6541 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6542 } 6543 break; 6544 case REFINER_HYBRID_HEX_3D: 6545 if ((p >= vStart) && (p < vEnd)) { 6546 /* Interior vertices stay the same */ 6547 newp = vStartNew + (p - vStart); 6548 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6549 } else if ((p >= eStart) && (p < eMax)) { 6550 /* Interior edges add new edges and vertex */ 6551 for (r = 0; r < 2; ++r) { 6552 newp = eStartNew + (p - eStart)*2 + r; 6553 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6554 } 6555 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6556 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6557 } else if ((p >= eMax) && (p < eEnd)) { 6558 /* Hybrid edges stay the same */ 6559 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6560 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6561 } else if ((p >= fStart) && (p < fMax)) { 6562 /* Interior faces add new faces, edges, and vertex */ 6563 for (r = 0; r < 4; ++r) { 6564 newp = fStartNew + (p - fStart)*4 + r; 6565 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6566 } 6567 for (r = 0; r < 4; ++r) { 6568 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6569 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6570 } 6571 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6572 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6573 } else if ((p >= fMax) && (p < fEnd)) { 6574 /* Hybrid faces add new faces and edges */ 6575 for (r = 0; r < 2; ++r) { 6576 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6577 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6578 } 6579 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6580 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6581 } else if ((p >= cStart) && (p < cMax)) { 6582 /* Interior cells add new cells, faces, edges, and vertex */ 6583 for (r = 0; r < 8; ++r) { 6584 newp = cStartNew + (p - cStart)*8 + r; 6585 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6586 } 6587 for (r = 0; r < 12; ++r) { 6588 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6589 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6590 } 6591 for (r = 0; r < 6; ++r) { 6592 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6593 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6594 } 6595 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6596 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6597 } else if ((p >= cMax) && (p < cEnd)) { 6598 /* Hybrid cells add new cells, faces, and edges */ 6599 for (r = 0; r < 4; ++r) { 6600 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6601 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6602 } 6603 for (r = 0; r < 4; ++r) { 6604 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6605 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6606 } 6607 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6608 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6609 } 6610 break; 6611 default: 6612 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6613 } 6614 } 6615 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6616 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6617 } 6618 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6619 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6620 if (0) { 6621 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6622 } 6623 } 6624 PetscFunctionReturn(0); 6625 } 6626 6627 /* This will only work for interpolated meshes */ 6628 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6629 { 6630 DM rdm; 6631 PetscInt *depthSize; 6632 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6633 PetscErrorCode ierr; 6634 6635 PetscFunctionBegin; 6636 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6637 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6638 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6639 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 6640 /* Calculate number of new points of each depth */ 6641 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6642 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 6643 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 6644 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6645 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6646 /* Step 1: Set chart */ 6647 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6648 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6649 /* Step 2: Set cone/support sizes */ 6650 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6651 /* Step 3: Setup refined DM */ 6652 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6653 /* Step 4: Set cones and supports */ 6654 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6655 /* Step 5: Stratify */ 6656 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6657 /* Step 6: Create pointSF */ 6658 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6659 /* Step 7: Set coordinates for vertices */ 6660 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6661 /* Step 8: Create labels */ 6662 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6663 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6664 6665 *dmRefined = rdm; 6666 PetscFunctionReturn(0); 6667 } 6668 6669 /*@ 6670 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 6671 6672 Input Parameter: 6673 . dm - The coarse DM 6674 6675 Output Parameter: 6676 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 6677 6678 Level: developer 6679 6680 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 6681 @*/ 6682 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 6683 { 6684 CellRefiner cellRefiner; 6685 PetscInt *depthSize, *fpoints; 6686 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6687 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 6688 PetscErrorCode ierr; 6689 6690 PetscFunctionBegin; 6691 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6692 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6693 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6694 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 6695 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 6696 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6697 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6698 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 6699 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 6700 switch (cellRefiner) { 6701 case REFINER_SIMPLEX_1D: 6702 case REFINER_SIMPLEX_2D: 6703 case REFINER_HYBRID_SIMPLEX_2D: 6704 case REFINER_HEX_2D: 6705 case REFINER_HYBRID_HEX_2D: 6706 case REFINER_SIMPLEX_3D: 6707 case REFINER_HYBRID_SIMPLEX_3D: 6708 case REFINER_HEX_3D: 6709 case REFINER_HYBRID_HEX_3D: 6710 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 6711 break; 6712 default: 6713 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 6714 } 6715 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 6716 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6717 PetscFunctionReturn(0); 6718 } 6719 6720 /*@ 6721 DMPlexSetRefinementUniform - Set the flag for uniform refinement 6722 6723 Input Parameters: 6724 + dm - The DM 6725 - refinementUniform - The flag for uniform refinement 6726 6727 Level: developer 6728 6729 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6730 @*/ 6731 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6732 { 6733 DM_Plex *mesh = (DM_Plex*) dm->data; 6734 6735 PetscFunctionBegin; 6736 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6737 mesh->refinementUniform = refinementUniform; 6738 PetscFunctionReturn(0); 6739 } 6740 6741 /*@ 6742 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 6743 6744 Input Parameter: 6745 . dm - The DM 6746 6747 Output Parameter: 6748 . refinementUniform - The flag for uniform refinement 6749 6750 Level: developer 6751 6752 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6753 @*/ 6754 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6755 { 6756 DM_Plex *mesh = (DM_Plex*) dm->data; 6757 6758 PetscFunctionBegin; 6759 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6760 PetscValidPointer(refinementUniform, 2); 6761 *refinementUniform = mesh->refinementUniform; 6762 PetscFunctionReturn(0); 6763 } 6764 6765 /*@ 6766 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 6767 6768 Input Parameters: 6769 + dm - The DM 6770 - refinementLimit - The maximum cell volume in the refined mesh 6771 6772 Level: developer 6773 6774 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6775 @*/ 6776 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6777 { 6778 DM_Plex *mesh = (DM_Plex*) dm->data; 6779 6780 PetscFunctionBegin; 6781 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6782 mesh->refinementLimit = refinementLimit; 6783 PetscFunctionReturn(0); 6784 } 6785 6786 /*@ 6787 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 6788 6789 Input Parameter: 6790 . dm - The DM 6791 6792 Output Parameter: 6793 . refinementLimit - The maximum cell volume in the refined mesh 6794 6795 Level: developer 6796 6797 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6798 @*/ 6799 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6800 { 6801 DM_Plex *mesh = (DM_Plex*) dm->data; 6802 6803 PetscFunctionBegin; 6804 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6805 PetscValidPointer(refinementLimit, 2); 6806 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6807 *refinementLimit = mesh->refinementLimit; 6808 PetscFunctionReturn(0); 6809 } 6810 6811 /*@ 6812 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 6813 6814 Input Parameters: 6815 + dm - The DM 6816 - refinementFunc - Function giving the maximum cell volume in the refined mesh 6817 6818 Note: The calling sequence is refinementFunc(coords, limit) 6819 $ coords - Coordinates of the current point, usually a cell centroid 6820 $ limit - The maximum cell volume for a cell containing this point 6821 6822 Level: developer 6823 6824 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6825 @*/ 6826 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 6827 { 6828 DM_Plex *mesh = (DM_Plex*) dm->data; 6829 6830 PetscFunctionBegin; 6831 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6832 mesh->refinementFunc = refinementFunc; 6833 PetscFunctionReturn(0); 6834 } 6835 6836 /*@ 6837 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 6838 6839 Input Parameter: 6840 . dm - The DM 6841 6842 Output Parameter: 6843 . refinementFunc - Function giving the maximum cell volume in the refined mesh 6844 6845 Note: The calling sequence is refinementFunc(coords, limit) 6846 $ coords - Coordinates of the current point, usually a cell centroid 6847 $ limit - The maximum cell volume for a cell containing this point 6848 6849 Level: developer 6850 6851 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6852 @*/ 6853 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 6854 { 6855 DM_Plex *mesh = (DM_Plex*) dm->data; 6856 6857 PetscFunctionBegin; 6858 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6859 PetscValidPointer(refinementFunc, 2); 6860 *refinementFunc = mesh->refinementFunc; 6861 PetscFunctionReturn(0); 6862 } 6863 6864 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6865 { 6866 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 6867 PetscErrorCode ierr; 6868 6869 PetscFunctionBegin; 6870 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6871 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6872 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 6873 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6874 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 6875 switch (dim) { 6876 case 1: 6877 switch (coneSize) { 6878 case 2: 6879 *cellRefiner = REFINER_SIMPLEX_1D; 6880 break; 6881 default: 6882 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6883 } 6884 break; 6885 case 2: 6886 switch (coneSize) { 6887 case 3: 6888 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 6889 else *cellRefiner = REFINER_SIMPLEX_2D; 6890 break; 6891 case 4: 6892 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 6893 else *cellRefiner = REFINER_HEX_2D; 6894 break; 6895 default: 6896 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6897 } 6898 break; 6899 case 3: 6900 switch (coneSize) { 6901 case 4: 6902 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 6903 else *cellRefiner = REFINER_SIMPLEX_3D; 6904 break; 6905 case 6: 6906 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 6907 else *cellRefiner = REFINER_HEX_3D; 6908 break; 6909 default: 6910 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6911 } 6912 break; 6913 default: 6914 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6915 } 6916 PetscFunctionReturn(0); 6917 } 6918