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 > 1.0e-10) {*inside = PETSC_FALSE; break;} 146 break; 147 case REFINER_HEX_2D: 148 for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*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_SIMPLEX_TO_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) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 189 depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */ 190 break; 191 case REFINER_HEX_2D: 192 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 193 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 194 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 195 break; 196 case REFINER_HYBRID_HEX_2D: 197 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 198 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 199 /* Quadrilateral */ 200 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 201 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 202 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 203 /* Segment Prisms */ 204 depthSize[0] += 0; /* No hybrid vertices */ 205 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 206 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 207 break; 208 case REFINER_SIMPLEX_3D: 209 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 210 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 */ 211 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 212 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 213 break; 214 case REFINER_HYBRID_SIMPLEX_3D: 215 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 216 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 217 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 218 /* Tetrahedra */ 219 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 220 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 */ 221 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 222 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 223 /* Triangular Prisms */ 224 depthSize[0] += 0; /* No hybrid vertices */ 225 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 226 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 227 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 228 break; 229 case REFINER_SIMPLEX_TO_HEX_3D: 230 depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */ 231 depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + 4*(cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 4 for each cell */ 232 depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */ 233 depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 234 break; 235 case REFINER_HEX_3D: 236 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 237 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 */ 238 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 239 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 240 break; 241 case REFINER_HYBRID_HEX_3D: 242 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 243 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 244 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 245 /* Hexahedra */ 246 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 247 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 */ 248 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 249 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 250 /* Quadrilateral Prisms */ 251 depthSize[0] += 0; /* No hybrid vertices */ 252 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 253 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 254 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 255 break; 256 default: 257 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 258 } 259 PetscFunctionReturn(0); 260 } 261 262 /* Return triangle edge for orientation o, if it is r for o == 0 */ 263 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 264 return (o < 0 ? 2-(o+r) : o+r)%3; 265 } 266 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 267 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 268 } 269 270 /* Return triangle subface for orientation o, if it is r for o == 0 */ 271 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 272 return (o < 0 ? 3-(o+r) : o+r)%3; 273 } 274 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 275 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 276 } 277 278 /* Return the interior edge number connecting the midpoints of the triangle edges r 279 and r+1 in the transitive closure for triangle orientation o */ 280 PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) { 281 return (o < 0 ? 1-(o+r) : o+r)%3; 282 } 283 PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) { 284 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 285 } 286 287 /* Return the interior edge number connecting the midpoint of the triangle edge r 288 (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */ 289 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) { 290 return (o < 0 ? 2-(o+r) : o+r)%3; 291 } 292 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) { 293 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 294 } 295 296 /* Return quad edge for orientation o, if it is r for o == 0 */ 297 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 298 return (o < 0 ? 3-(o+r) : o+r)%4; 299 } 300 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 301 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 302 } 303 304 /* Return quad subface for orientation o, if it is r for o == 0 */ 305 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 306 return (o < 0 ? 4-(o+r) : o+r)%4; 307 } 308 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 309 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 310 } 311 312 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 313 { 314 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 315 PetscErrorCode ierr; 316 317 PetscFunctionBegin; 318 if (!refiner) PetscFunctionReturn(0); 319 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 320 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 321 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 322 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 323 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 324 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 325 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 326 switch (refiner) { 327 case REFINER_SIMPLEX_1D: 328 /* All cells have 2 vertices */ 329 for (c = cStart; c < cEnd; ++c) { 330 for (r = 0; r < 2; ++r) { 331 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 332 333 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 334 } 335 } 336 /* Old vertices have identical supports */ 337 for (v = vStart; v < vEnd; ++v) { 338 const PetscInt newp = vStartNew + (v - vStart); 339 PetscInt size; 340 341 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 342 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 343 } 344 /* Cell vertices have support 2 */ 345 for (c = cStart; c < cEnd; ++c) { 346 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 347 348 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 349 } 350 break; 351 case REFINER_SIMPLEX_2D: 352 /* All cells have 3 faces */ 353 for (c = cStart; c < cEnd; ++c) { 354 for (r = 0; r < 4; ++r) { 355 const PetscInt newp = (c - cStart)*4 + r; 356 357 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 358 } 359 } 360 /* Split faces have 2 vertices and the same cells as the parent */ 361 for (f = fStart; f < fEnd; ++f) { 362 for (r = 0; r < 2; ++r) { 363 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 364 PetscInt size; 365 366 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 367 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 368 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 369 } 370 } 371 /* Interior faces have 2 vertices and 2 cells */ 372 for (c = cStart; c < cEnd; ++c) { 373 for (r = 0; r < 3; ++r) { 374 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 375 376 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 377 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 378 } 379 } 380 /* Old vertices have identical supports */ 381 for (v = vStart; v < vEnd; ++v) { 382 const PetscInt newp = vStartNew + (v - vStart); 383 PetscInt size; 384 385 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 386 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 387 } 388 /* Face vertices have 2 + cells*2 supports */ 389 for (f = fStart; f < fEnd; ++f) { 390 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 391 PetscInt size; 392 393 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 394 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 395 } 396 break; 397 case REFINER_SIMPLEX_TO_HEX_2D: 398 /* All cells have 4 faces */ 399 for (c = cStart; c < cEnd; ++c) { 400 for (r = 0; r < 3; ++r) { 401 const PetscInt newp = (c - cStart)*3 + r; 402 403 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 404 } 405 } 406 /* Split faces have 2 vertices and the same cells as the parent */ 407 for (f = fStart; f < fEnd; ++f) { 408 for (r = 0; r < 2; ++r) { 409 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 410 PetscInt size; 411 412 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 413 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 414 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 415 } 416 } 417 /* Interior faces have 2 vertices and 2 cells */ 418 for (c = cStart; c < cEnd; ++c) { 419 for (r = 0; r < 3; ++r) { 420 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 421 422 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 423 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 424 } 425 } 426 /* Old vertices have identical supports */ 427 for (v = vStart; v < vEnd; ++v) { 428 const PetscInt newp = vStartNew + (v - vStart); 429 PetscInt size; 430 431 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 432 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 433 } 434 /* Split-face vertices have cells + 2 supports */ 435 for (f = fStart; f < fEnd; ++f) { 436 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 437 PetscInt size; 438 439 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 440 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 441 } 442 /* Interior vertices have 3 supports */ 443 for (c = cStart; c < cEnd; ++c) { 444 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 445 446 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 447 } 448 break; 449 case REFINER_HEX_2D: 450 /* All cells have 4 faces */ 451 for (c = cStart; c < cEnd; ++c) { 452 for (r = 0; r < 4; ++r) { 453 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 454 455 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 456 } 457 } 458 /* Split faces have 2 vertices and the same cells as the parent */ 459 for (f = fStart; f < fEnd; ++f) { 460 for (r = 0; r < 2; ++r) { 461 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 462 PetscInt size; 463 464 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 465 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 466 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 467 } 468 } 469 /* Interior faces have 2 vertices and 2 cells */ 470 for (c = cStart; c < cEnd; ++c) { 471 for (r = 0; r < 4; ++r) { 472 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 473 474 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 475 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 476 } 477 } 478 /* Old vertices have identical supports */ 479 for (v = vStart; v < vEnd; ++v) { 480 const PetscInt newp = vStartNew + (v - vStart); 481 PetscInt size; 482 483 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 484 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 485 } 486 /* Face vertices have 2 + cells supports */ 487 for (f = fStart; f < fEnd; ++f) { 488 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 489 PetscInt size; 490 491 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 492 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 493 } 494 /* Cell vertices have 4 supports */ 495 for (c = cStart; c < cEnd; ++c) { 496 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 497 498 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 499 } 500 break; 501 case REFINER_HYBRID_SIMPLEX_2D: 502 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 503 cMax = PetscMin(cEnd, cMax); 504 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 505 fMax = PetscMin(fEnd, fMax); 506 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 507 /* Interior cells have 3 faces */ 508 for (c = cStart; c < cMax; ++c) { 509 for (r = 0; r < 4; ++r) { 510 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 511 512 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 513 } 514 } 515 /* Hybrid cells have 4 faces */ 516 for (c = cMax; c < cEnd; ++c) { 517 for (r = 0; r < 2; ++r) { 518 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 519 520 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 521 } 522 } 523 /* Interior split faces have 2 vertices and the same cells as the parent */ 524 for (f = fStart; f < fMax; ++f) { 525 for (r = 0; r < 2; ++r) { 526 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 527 PetscInt size; 528 529 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 530 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 531 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 532 } 533 } 534 /* Interior cell faces have 2 vertices and 2 cells */ 535 for (c = cStart; c < cMax; ++c) { 536 for (r = 0; r < 3; ++r) { 537 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 538 539 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 540 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 541 } 542 } 543 /* Hybrid faces have 2 vertices and the same cells */ 544 for (f = fMax; f < fEnd; ++f) { 545 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 546 PetscInt size; 547 548 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 549 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 550 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 551 } 552 /* Hybrid cell faces have 2 vertices and 2 cells */ 553 for (c = cMax; c < cEnd; ++c) { 554 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 555 556 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 557 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 558 } 559 /* Old vertices have identical supports */ 560 for (v = vStart; v < vEnd; ++v) { 561 const PetscInt newp = vStartNew + (v - vStart); 562 PetscInt size; 563 564 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 565 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 566 } 567 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 568 for (f = fStart; f < fMax; ++f) { 569 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 570 const PetscInt *support; 571 PetscInt size, newSize = 2, s; 572 573 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 574 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 575 for (s = 0; s < size; ++s) { 576 if (support[s] >= cMax) newSize += 1; 577 else newSize += 2; 578 } 579 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 580 } 581 break; 582 case REFINER_HYBRID_HEX_2D: 583 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 584 cMax = PetscMin(cEnd, cMax); 585 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 586 fMax = PetscMin(fEnd, fMax); 587 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 588 /* Interior cells have 4 faces */ 589 for (c = cStart; c < cMax; ++c) { 590 for (r = 0; r < 4; ++r) { 591 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 592 593 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 594 } 595 } 596 /* Hybrid cells have 4 faces */ 597 for (c = cMax; c < cEnd; ++c) { 598 for (r = 0; r < 2; ++r) { 599 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 600 601 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 602 } 603 } 604 /* Interior split faces have 2 vertices and the same cells as the parent */ 605 for (f = fStart; f < fMax; ++f) { 606 for (r = 0; r < 2; ++r) { 607 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 608 PetscInt size; 609 610 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 611 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 612 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 613 } 614 } 615 /* Interior cell faces have 2 vertices and 2 cells */ 616 for (c = cStart; c < cMax; ++c) { 617 for (r = 0; r < 4; ++r) { 618 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 619 620 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 621 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 622 } 623 } 624 /* Hybrid faces have 2 vertices and the same cells */ 625 for (f = fMax; f < fEnd; ++f) { 626 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 627 PetscInt size; 628 629 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 630 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 631 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 632 } 633 /* Hybrid cell faces have 2 vertices and 2 cells */ 634 for (c = cMax; c < cEnd; ++c) { 635 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 636 637 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 638 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 639 } 640 /* Old vertices have identical supports */ 641 for (v = vStart; v < vEnd; ++v) { 642 const PetscInt newp = vStartNew + (v - vStart); 643 PetscInt size; 644 645 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 646 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 647 } 648 /* Face vertices have 2 + cells supports */ 649 for (f = fStart; f < fMax; ++f) { 650 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 651 PetscInt size; 652 653 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 654 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 655 } 656 /* Cell vertices have 4 supports */ 657 for (c = cStart; c < cMax; ++c) { 658 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 659 660 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 661 } 662 break; 663 case REFINER_SIMPLEX_3D: 664 /* All cells have 4 faces */ 665 for (c = cStart; c < cEnd; ++c) { 666 for (r = 0; r < 8; ++r) { 667 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 668 669 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 670 } 671 } 672 /* Split faces have 3 edges and the same cells as the parent */ 673 for (f = fStart; f < fEnd; ++f) { 674 for (r = 0; r < 4; ++r) { 675 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 676 PetscInt size; 677 678 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 679 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 680 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 681 } 682 } 683 /* Interior cell faces have 3 edges and 2 cells */ 684 for (c = cStart; c < cEnd; ++c) { 685 for (r = 0; r < 8; ++r) { 686 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 687 688 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 689 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 690 } 691 } 692 /* Split edges have 2 vertices and the same faces */ 693 for (e = eStart; e < eEnd; ++e) { 694 for (r = 0; r < 2; ++r) { 695 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 696 PetscInt size; 697 698 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 699 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 700 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 701 } 702 } 703 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 704 for (f = fStart; f < fEnd; ++f) { 705 for (r = 0; r < 3; ++r) { 706 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 707 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 708 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 709 710 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 711 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 712 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 713 for (s = 0; s < supportSize; ++s) { 714 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 715 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 716 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 717 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 718 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 719 er = GetTriMidEdgeInverse_Static(ornt[c], r); 720 if (er == eint[c]) { 721 intFaces += 1; 722 } else { 723 intFaces += 2; 724 } 725 } 726 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 727 } 728 } 729 /* Interior cell edges have 2 vertices and 4 faces */ 730 for (c = cStart; c < cEnd; ++c) { 731 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 732 733 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 734 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 735 } 736 /* Old vertices have identical supports */ 737 for (v = vStart; v < vEnd; ++v) { 738 const PetscInt newp = vStartNew + (v - vStart); 739 PetscInt size; 740 741 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 742 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 743 } 744 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 745 for (e = eStart; e < eEnd; ++e) { 746 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 747 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 748 749 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 750 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 751 for (s = 0; s < starSize*2; s += 2) { 752 const PetscInt *cone, *ornt; 753 PetscInt e01, e23; 754 755 if ((star[s] >= cStart) && (star[s] < cEnd)) { 756 /* Check edge 0-1 */ 757 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 758 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 759 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 760 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 761 /* Check edge 2-3 */ 762 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 763 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 764 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 765 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 766 if ((e01 == e) || (e23 == e)) ++cellSize; 767 } 768 } 769 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 770 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 771 } 772 break; 773 case REFINER_HYBRID_SIMPLEX_3D: 774 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 775 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 776 /* Interior cells have 4 faces */ 777 for (c = cStart; c < cMax; ++c) { 778 for (r = 0; r < 8; ++r) { 779 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 780 781 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 782 } 783 } 784 /* Hybrid cells have 5 faces */ 785 for (c = cMax; c < cEnd; ++c) { 786 for (r = 0; r < 4; ++r) { 787 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 788 789 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 790 } 791 } 792 /* Interior split faces have 3 edges and the same cells as the parent */ 793 for (f = fStart; f < fMax; ++f) { 794 for (r = 0; r < 4; ++r) { 795 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 796 PetscInt size; 797 798 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 799 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 800 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 801 } 802 } 803 /* Interior cell faces have 3 edges and 2 cells */ 804 for (c = cStart; c < cMax; ++c) { 805 for (r = 0; r < 8; ++r) { 806 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 807 808 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 809 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 810 } 811 } 812 /* Hybrid split faces have 4 edges and the same cells as the parent */ 813 for (f = fMax; f < fEnd; ++f) { 814 for (r = 0; r < 2; ++r) { 815 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 816 PetscInt size; 817 818 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 819 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 820 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 821 } 822 } 823 /* Hybrid cells faces have 4 edges and 2 cells */ 824 for (c = cMax; c < cEnd; ++c) { 825 for (r = 0; r < 3; ++r) { 826 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 827 828 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 829 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 830 } 831 } 832 /* Interior split edges have 2 vertices and the same faces */ 833 for (e = eStart; e < eMax; ++e) { 834 for (r = 0; r < 2; ++r) { 835 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 836 PetscInt size; 837 838 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 839 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 840 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 841 } 842 } 843 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 844 for (f = fStart; f < fMax; ++f) { 845 for (r = 0; r < 3; ++r) { 846 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 847 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 848 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 849 850 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 851 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 852 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 853 for (s = 0; s < supportSize; ++s) { 854 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 855 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 856 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 857 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 858 if (support[s] < cMax) { 859 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 860 er = GetTriMidEdgeInverse_Static(ornt[c], r); 861 if (er == eint[c]) { 862 intFaces += 1; 863 } else { 864 intFaces += 2; 865 } 866 } else { 867 intFaces += 1; 868 } 869 } 870 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 871 } 872 } 873 /* Interior cell edges have 2 vertices and 4 faces */ 874 for (c = cStart; c < cMax; ++c) { 875 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 876 877 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 878 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 879 } 880 /* Hybrid edges have 2 vertices and the same faces */ 881 for (e = eMax; e < eEnd; ++e) { 882 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 883 PetscInt size; 884 885 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 886 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 887 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 888 } 889 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 890 for (f = fMax; f < fEnd; ++f) { 891 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 892 PetscInt size; 893 894 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 895 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 896 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 897 } 898 /* Interior vertices have identical supports */ 899 for (v = vStart; v < vEnd; ++v) { 900 const PetscInt newp = vStartNew + (v - vStart); 901 PetscInt size; 902 903 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 904 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 905 } 906 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 907 for (e = eStart; e < eMax; ++e) { 908 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 909 const PetscInt *support; 910 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 911 912 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 913 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 914 for (s = 0; s < size; ++s) { 915 if (support[s] < fMax) faceSize += 2; 916 else faceSize += 1; 917 } 918 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 919 for (s = 0; s < starSize*2; s += 2) { 920 const PetscInt *cone, *ornt; 921 PetscInt e01, e23; 922 923 if ((star[s] >= cStart) && (star[s] < cMax)) { 924 /* Check edge 0-1 */ 925 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 926 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 927 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 928 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 929 /* Check edge 2-3 */ 930 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 931 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 932 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 933 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 934 if ((e01 == e) || (e23 == e)) ++cellSize; 935 } 936 } 937 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 938 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 939 } 940 break; 941 case REFINER_SIMPLEX_TO_HEX_3D: 942 /* All cells have 6 faces */ 943 for (c = cStart; c < cEnd; ++c) { 944 for (r = 0; r < 4; ++r) { 945 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 946 947 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 948 } 949 } 950 /* Split faces have 4 edges and the same cells as the parent */ 951 for (f = fStart; f < fEnd; ++f) { 952 for (r = 0; r < 3; ++r) { 953 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 954 PetscInt size; 955 956 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 957 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 958 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 959 } 960 } 961 /* Interior cell faces have 4 edges and 2 cells */ 962 for (c = cStart; c < cEnd; ++c) { 963 for (r = 0; r < 6; ++r) { 964 const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r; 965 966 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 967 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 968 } 969 } 970 /* Split edges have 2 vertices and the same faces */ 971 for (e = eStart; e < eEnd; ++e) { 972 for (r = 0; r < 2; ++r) { 973 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 974 PetscInt size; 975 976 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 977 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 978 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 979 } 980 } 981 /* Face edges have 2 vertices and 2 + cell faces supports */ 982 for (f = fStart; f < fEnd; ++f) { 983 for (r = 0; r < 3; ++r) { 984 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 985 PetscInt size; 986 987 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 988 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 989 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 990 } 991 } 992 /* Interior cell edges have 2 vertices and 3 faces */ 993 for (c = cStart; c < cEnd; ++c) { 994 for (r = 0; r < 4; ++r) { 995 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 996 997 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 998 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 999 } 1000 } 1001 /* Old vertices have identical supports */ 1002 for (v = vStart; v < vEnd; ++v) { 1003 const PetscInt newp = vStartNew + (v - vStart); 1004 PetscInt size; 1005 1006 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1007 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1008 } 1009 /* Edge vertices have 2 + faces supports */ 1010 for (e = eStart; e < eEnd; ++e) { 1011 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1012 PetscInt size; 1013 1014 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1015 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1016 } 1017 /* Face vertices have 3 + cells supports */ 1018 for (f = fStart; f < fEnd; ++f) { 1019 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 1020 PetscInt size; 1021 1022 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1023 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1024 } 1025 /* Interior cell vertices have 4 supports */ 1026 for (c = cStart; c < cEnd; ++c) { 1027 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart; 1028 1029 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1030 } 1031 break; 1032 case REFINER_HEX_3D: 1033 /* All cells have 6 faces */ 1034 for (c = cStart; c < cEnd; ++c) { 1035 for (r = 0; r < 8; ++r) { 1036 const PetscInt newp = (c - cStart)*8 + r; 1037 1038 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1039 } 1040 } 1041 /* Split faces have 4 edges and the same cells as the parent */ 1042 for (f = fStart; f < fEnd; ++f) { 1043 for (r = 0; r < 4; ++r) { 1044 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1045 PetscInt size; 1046 1047 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1048 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1049 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1050 } 1051 } 1052 /* Interior faces have 4 edges and 2 cells */ 1053 for (c = cStart; c < cEnd; ++c) { 1054 for (r = 0; r < 12; ++r) { 1055 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 1056 1057 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1058 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1059 } 1060 } 1061 /* Split edges have 2 vertices and the same faces as the parent */ 1062 for (e = eStart; e < eEnd; ++e) { 1063 for (r = 0; r < 2; ++r) { 1064 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1065 PetscInt size; 1066 1067 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1068 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1069 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1070 } 1071 } 1072 /* Face edges have 2 vertices and 2+cells faces */ 1073 for (f = fStart; f < fEnd; ++f) { 1074 for (r = 0; r < 4; ++r) { 1075 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 1076 PetscInt size; 1077 1078 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1079 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1080 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1081 } 1082 } 1083 /* Cell edges have 2 vertices and 4 faces */ 1084 for (c = cStart; c < cEnd; ++c) { 1085 for (r = 0; r < 6; ++r) { 1086 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 1087 1088 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1089 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1090 } 1091 } 1092 /* Old vertices have identical supports */ 1093 for (v = vStart; v < vEnd; ++v) { 1094 const PetscInt newp = vStartNew + (v - vStart); 1095 PetscInt size; 1096 1097 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1098 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1099 } 1100 /* Edge vertices have 2 + faces supports */ 1101 for (e = eStart; e < eEnd; ++e) { 1102 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1103 PetscInt size; 1104 1105 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1106 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1107 } 1108 /* Face vertices have 4 + cells supports */ 1109 for (f = fStart; f < fEnd; ++f) { 1110 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 1111 PetscInt size; 1112 1113 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1114 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1115 } 1116 /* Cell vertices have 6 supports */ 1117 for (c = cStart; c < cEnd; ++c) { 1118 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 1119 1120 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1121 } 1122 break; 1123 case REFINER_HYBRID_HEX_3D: 1124 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 1125 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1126 /* Interior cells have 6 faces */ 1127 for (c = cStart; c < cMax; ++c) { 1128 for (r = 0; r < 8; ++r) { 1129 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1130 1131 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1132 } 1133 } 1134 /* Hybrid cells have 6 faces */ 1135 for (c = cMax; c < cEnd; ++c) { 1136 for (r = 0; r < 4; ++r) { 1137 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1138 1139 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1140 } 1141 } 1142 /* Interior split faces have 4 edges and the same cells as the parent */ 1143 for (f = fStart; f < fMax; ++f) { 1144 for (r = 0; r < 4; ++r) { 1145 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1146 PetscInt size; 1147 1148 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1149 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1150 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1151 } 1152 } 1153 /* Interior cell faces have 4 edges and 2 cells */ 1154 for (c = cStart; c < cMax; ++c) { 1155 for (r = 0; r < 12; ++r) { 1156 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1157 1158 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1159 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1160 } 1161 } 1162 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1163 for (f = fMax; f < fEnd; ++f) { 1164 for (r = 0; r < 2; ++r) { 1165 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1166 PetscInt size; 1167 1168 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1169 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1170 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1171 } 1172 } 1173 /* Hybrid cells faces have 4 edges and 2 cells */ 1174 for (c = cMax; c < cEnd; ++c) { 1175 for (r = 0; r < 4; ++r) { 1176 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1177 1178 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1179 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1180 } 1181 } 1182 /* Interior split edges have 2 vertices and the same faces as the parent */ 1183 for (e = eStart; e < eMax; ++e) { 1184 for (r = 0; r < 2; ++r) { 1185 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1186 PetscInt size; 1187 1188 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1189 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1190 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1191 } 1192 } 1193 /* Interior face edges have 2 vertices and 2+cells faces */ 1194 for (f = fStart; f < fMax; ++f) { 1195 for (r = 0; r < 4; ++r) { 1196 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1197 PetscInt size; 1198 1199 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1200 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1201 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1202 } 1203 } 1204 /* Interior cell edges have 2 vertices and 4 faces */ 1205 for (c = cStart; c < cMax; ++c) { 1206 for (r = 0; r < 6; ++r) { 1207 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1208 1209 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1210 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1211 } 1212 } 1213 /* Hybrid edges have 2 vertices and the same faces */ 1214 for (e = eMax; e < eEnd; ++e) { 1215 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1216 PetscInt size; 1217 1218 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1219 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1220 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1221 } 1222 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1223 for (f = fMax; f < fEnd; ++f) { 1224 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1225 PetscInt size; 1226 1227 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1228 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1229 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1230 } 1231 /* Hybrid cell edges have 2 vertices and 4 faces */ 1232 for (c = cMax; c < cEnd; ++c) { 1233 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1234 1235 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1236 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1237 } 1238 /* Interior vertices have identical supports */ 1239 for (v = vStart; v < vEnd; ++v) { 1240 const PetscInt newp = vStartNew + (v - vStart); 1241 PetscInt size; 1242 1243 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1244 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1245 } 1246 /* Interior edge vertices have 2 + faces supports */ 1247 for (e = eStart; e < eMax; ++e) { 1248 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1249 PetscInt size; 1250 1251 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1252 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1253 } 1254 /* Interior face vertices have 4 + cells supports */ 1255 for (f = fStart; f < fMax; ++f) { 1256 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1257 PetscInt size; 1258 1259 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1260 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1261 } 1262 /* Interior cell vertices have 6 supports */ 1263 for (c = cStart; c < cMax; ++c) { 1264 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1265 1266 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1267 } 1268 break; 1269 default: 1270 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1271 } 1272 PetscFunctionReturn(0); 1273 } 1274 1275 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1276 { 1277 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1278 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1279 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1280 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 1281 PetscErrorCode ierr; 1282 1283 PetscFunctionBegin; 1284 if (!refiner) PetscFunctionReturn(0); 1285 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1286 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1287 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1288 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1289 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1290 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1291 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1292 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1293 switch (refiner) { 1294 case REFINER_SIMPLEX_1D: 1295 /* Max support size of refined mesh is 2 */ 1296 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1297 /* All cells have 2 vertices */ 1298 for (c = cStart; c < cEnd; ++c) { 1299 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1300 1301 for (r = 0; r < 2; ++r) { 1302 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1303 const PetscInt *cone; 1304 PetscInt coneNew[2]; 1305 1306 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1307 coneNew[0] = vStartNew + (cone[0] - vStart); 1308 coneNew[1] = vStartNew + (cone[1] - vStart); 1309 coneNew[(r+1)%2] = newv; 1310 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1311 #if 1 1312 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew); 1313 for (p = 0; p < 2; ++p) { 1314 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); 1315 } 1316 #endif 1317 } 1318 } 1319 /* Old vertices have identical supports */ 1320 for (v = vStart; v < vEnd; ++v) { 1321 const PetscInt newp = vStartNew + (v - vStart); 1322 const PetscInt *support, *cone; 1323 PetscInt size, s; 1324 1325 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1326 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1327 for (s = 0; s < size; ++s) { 1328 PetscInt r = 0; 1329 1330 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1331 if (cone[1] == v) r = 1; 1332 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1333 } 1334 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1335 #if 1 1336 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1337 for (p = 0; p < size; ++p) { 1338 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); 1339 } 1340 #endif 1341 } 1342 /* Cell vertices have support of 2 cells */ 1343 for (c = cStart; c < cEnd; ++c) { 1344 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1345 1346 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1347 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1348 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1349 #if 1 1350 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1351 for (p = 0; p < 2; ++p) { 1352 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); 1353 } 1354 #endif 1355 } 1356 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1357 break; 1358 case REFINER_SIMPLEX_2D: 1359 /* 1360 2 1361 |\ 1362 | \ 1363 | \ 1364 | \ 1365 | C \ 1366 | \ 1367 | \ 1368 2---1---1 1369 |\ D / \ 1370 | 2 0 \ 1371 |A \ / B \ 1372 0---0-------1 1373 */ 1374 /* All cells have 3 faces */ 1375 for (c = cStart; c < cEnd; ++c) { 1376 const PetscInt newp = cStartNew + (c - cStart)*4; 1377 const PetscInt *cone, *ornt; 1378 PetscInt coneNew[3], orntNew[3]; 1379 1380 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1381 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1382 /* A triangle */ 1383 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1384 orntNew[0] = ornt[0]; 1385 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1386 orntNew[1] = -2; 1387 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1388 orntNew[2] = ornt[2]; 1389 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1390 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1391 #if 1 1392 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); 1393 for (p = 0; p < 3; ++p) { 1394 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); 1395 } 1396 #endif 1397 /* B triangle */ 1398 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1399 orntNew[0] = ornt[0]; 1400 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1401 orntNew[1] = ornt[1]; 1402 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1403 orntNew[2] = -2; 1404 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1405 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1406 #if 1 1407 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); 1408 for (p = 0; p < 3; ++p) { 1409 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); 1410 } 1411 #endif 1412 /* C triangle */ 1413 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1414 orntNew[0] = -2; 1415 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1416 orntNew[1] = ornt[1]; 1417 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1418 orntNew[2] = ornt[2]; 1419 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1420 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1421 #if 1 1422 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); 1423 for (p = 0; p < 3; ++p) { 1424 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); 1425 } 1426 #endif 1427 /* D triangle */ 1428 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1429 orntNew[0] = 0; 1430 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1431 orntNew[1] = 0; 1432 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1433 orntNew[2] = 0; 1434 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1435 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1436 #if 1 1437 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); 1438 for (p = 0; p < 3; ++p) { 1439 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); 1440 } 1441 #endif 1442 } 1443 /* Split faces have 2 vertices and the same cells as the parent */ 1444 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1445 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1446 for (f = fStart; f < fEnd; ++f) { 1447 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1448 1449 for (r = 0; r < 2; ++r) { 1450 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1451 const PetscInt *cone, *ornt, *support; 1452 PetscInt coneNew[2], coneSize, c, supportSize, s; 1453 1454 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1455 coneNew[0] = vStartNew + (cone[0] - vStart); 1456 coneNew[1] = vStartNew + (cone[1] - vStart); 1457 coneNew[(r+1)%2] = newv; 1458 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1459 #if 1 1460 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1461 for (p = 0; p < 2; ++p) { 1462 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); 1463 } 1464 #endif 1465 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1466 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1467 for (s = 0; s < supportSize; ++s) { 1468 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1469 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1470 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1471 for (c = 0; c < coneSize; ++c) { 1472 if (cone[c] == f) break; 1473 } 1474 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1475 } 1476 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1477 #if 1 1478 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1479 for (p = 0; p < supportSize; ++p) { 1480 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); 1481 } 1482 #endif 1483 } 1484 } 1485 /* Interior faces have 2 vertices and 2 cells */ 1486 for (c = cStart; c < cEnd; ++c) { 1487 const PetscInt *cone; 1488 1489 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1490 for (r = 0; r < 3; ++r) { 1491 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1492 PetscInt coneNew[2]; 1493 PetscInt supportNew[2]; 1494 1495 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1496 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1497 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1498 #if 1 1499 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1500 for (p = 0; p < 2; ++p) { 1501 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); 1502 } 1503 #endif 1504 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1505 supportNew[1] = (c - cStart)*4 + 3; 1506 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1507 #if 1 1508 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1509 for (p = 0; p < 2; ++p) { 1510 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); 1511 } 1512 #endif 1513 } 1514 } 1515 /* Old vertices have identical supports */ 1516 for (v = vStart; v < vEnd; ++v) { 1517 const PetscInt newp = vStartNew + (v - vStart); 1518 const PetscInt *support, *cone; 1519 PetscInt size, s; 1520 1521 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1522 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1523 for (s = 0; s < size; ++s) { 1524 PetscInt r = 0; 1525 1526 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1527 if (cone[1] == v) r = 1; 1528 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1529 } 1530 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1531 #if 1 1532 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1533 for (p = 0; p < size; ++p) { 1534 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); 1535 } 1536 #endif 1537 } 1538 /* Face vertices have 2 + cells*2 supports */ 1539 for (f = fStart; f < fEnd; ++f) { 1540 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1541 const PetscInt *cone, *support; 1542 PetscInt size, s; 1543 1544 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1545 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1546 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1547 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1548 for (s = 0; s < size; ++s) { 1549 PetscInt r = 0; 1550 1551 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1552 if (cone[1] == f) r = 1; 1553 else if (cone[2] == f) r = 2; 1554 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1555 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1556 } 1557 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1558 #if 1 1559 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1560 for (p = 0; p < 2+size*2; ++p) { 1561 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); 1562 } 1563 #endif 1564 } 1565 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1566 break; 1567 case REFINER_SIMPLEX_TO_HEX_2D: 1568 /* 1569 2 1570 |\ 1571 | \ 1572 | \ 1573 | \ 1574 | C \ 1575 | \ 1576 2 1 1577 |\ / \ 1578 | 2 1 \ 1579 | \/ \ 1580 | | \ 1581 |A | B \ 1582 | 0 \ 1583 | | \ 1584 0---0----------1 1585 */ 1586 /* All cells have 4 faces */ 1587 for (c = cStart; c < cEnd; ++c) { 1588 const PetscInt newp = cStartNew + (c - cStart)*3; 1589 const PetscInt *cone, *ornt; 1590 PetscInt coneNew[4], orntNew[4]; 1591 1592 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1593 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1594 /* A quad */ 1595 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1596 orntNew[0] = ornt[0]; 1597 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1598 orntNew[1] = 0; 1599 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1600 orntNew[2] = -2; 1601 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1602 orntNew[3] = ornt[2]; 1603 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1604 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1605 #if 1 1606 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); 1607 for (p = 0; p < 4; ++p) { 1608 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); 1609 } 1610 #endif 1611 /* B quad */ 1612 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1613 orntNew[0] = ornt[0]; 1614 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1615 orntNew[1] = ornt[1]; 1616 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1617 orntNew[2] = 0; 1618 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1619 orntNew[3] = -2; 1620 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1621 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1622 #if 1 1623 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); 1624 for (p = 0; p < 4; ++p) { 1625 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); 1626 } 1627 #endif 1628 /* C quad */ 1629 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1630 orntNew[0] = ornt[1]; 1631 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1632 orntNew[1] = ornt[2]; 1633 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1634 orntNew[2] = 0; 1635 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1636 orntNew[3] = -2; 1637 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1638 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1639 #if 1 1640 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); 1641 for (p = 0; p < 4; ++p) { 1642 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); 1643 } 1644 #endif 1645 } 1646 /* Split faces have 2 vertices and the same cells as the parent */ 1647 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1648 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1649 for (f = fStart; f < fEnd; ++f) { 1650 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1651 1652 for (r = 0; r < 2; ++r) { 1653 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1654 const PetscInt *cone, *ornt, *support; 1655 PetscInt coneNew[2], coneSize, c, supportSize, s; 1656 1657 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1658 coneNew[0] = vStartNew + (cone[0] - vStart); 1659 coneNew[1] = vStartNew + (cone[1] - vStart); 1660 coneNew[(r+1)%2] = newv; 1661 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1662 #if 1 1663 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1664 for (p = 0; p < 2; ++p) { 1665 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); 1666 } 1667 #endif 1668 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1669 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1670 for (s = 0; s < supportSize; ++s) { 1671 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1672 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1673 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1674 for (c = 0; c < coneSize; ++c) { 1675 if (cone[c] == f) break; 1676 } 1677 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1678 } 1679 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1680 #if 1 1681 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1682 for (p = 0; p < supportSize; ++p) { 1683 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); 1684 } 1685 #endif 1686 } 1687 } 1688 /* Interior faces have 2 vertices and 2 cells */ 1689 for (c = cStart; c < cEnd; ++c) { 1690 const PetscInt *cone; 1691 1692 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1693 for (r = 0; r < 3; ++r) { 1694 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1695 PetscInt coneNew[2]; 1696 PetscInt supportNew[2]; 1697 1698 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1699 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1700 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1701 #if 1 1702 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1703 for (p = 0; p < 2; ++p) { 1704 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); 1705 } 1706 #endif 1707 supportNew[0] = (c - cStart)*3 + r%3; 1708 supportNew[1] = (c - cStart)*3 + (r+1)%3; 1709 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1710 #if 1 1711 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1712 for (p = 0; p < 2; ++p) { 1713 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); 1714 } 1715 #endif 1716 } 1717 } 1718 /* Old vertices have identical supports */ 1719 for (v = vStart; v < vEnd; ++v) { 1720 const PetscInt newp = vStartNew + (v - vStart); 1721 const PetscInt *support, *cone; 1722 PetscInt size, s; 1723 1724 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1725 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1726 for (s = 0; s < size; ++s) { 1727 PetscInt r = 0; 1728 1729 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1730 if (cone[1] == v) r = 1; 1731 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1732 } 1733 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1734 #if 1 1735 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1736 for (p = 0; p < size; ++p) { 1737 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); 1738 } 1739 #endif 1740 } 1741 /* Split-face vertices have cells + 2 supports */ 1742 for (f = fStart; f < fEnd; ++f) { 1743 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1744 const PetscInt *cone, *support; 1745 PetscInt size, s; 1746 1747 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1748 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1749 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1750 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1751 for (s = 0; s < size; ++s) { 1752 PetscInt r = 0; 1753 1754 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1755 if (cone[1] == f) r = 1; 1756 else if (cone[2] == f) r = 2; 1757 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1758 } 1759 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1760 #if 1 1761 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1762 for (p = 0; p < 2+size; ++p) { 1763 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); 1764 } 1765 #endif 1766 } 1767 /* Interior vertices vertices have 3 supports */ 1768 for (c = cStart; c < cEnd; ++c) { 1769 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 1770 1771 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1772 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1773 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1774 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1775 } 1776 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1777 break; 1778 case REFINER_HEX_2D: 1779 /* 1780 3---------2---------2 1781 | | | 1782 | D 2 C | 1783 | | | 1784 3----3----0----1----1 1785 | | | 1786 | A 0 B | 1787 | | | 1788 0---------0---------1 1789 */ 1790 /* All cells have 4 faces */ 1791 for (c = cStart; c < cEnd; ++c) { 1792 const PetscInt newp = (c - cStart)*4; 1793 const PetscInt *cone, *ornt; 1794 PetscInt coneNew[4], orntNew[4]; 1795 1796 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1797 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1798 /* A quad */ 1799 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1800 orntNew[0] = ornt[0]; 1801 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1802 orntNew[1] = 0; 1803 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1804 orntNew[2] = -2; 1805 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1806 orntNew[3] = ornt[3]; 1807 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1808 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1809 #if 1 1810 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); 1811 for (p = 0; p < 4; ++p) { 1812 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); 1813 } 1814 #endif 1815 /* B quad */ 1816 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1817 orntNew[0] = ornt[0]; 1818 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1819 orntNew[1] = ornt[1]; 1820 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1821 orntNew[2] = 0; 1822 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1823 orntNew[3] = -2; 1824 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1825 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1826 #if 1 1827 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); 1828 for (p = 0; p < 4; ++p) { 1829 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); 1830 } 1831 #endif 1832 /* C quad */ 1833 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1834 orntNew[0] = -2; 1835 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1836 orntNew[1] = ornt[1]; 1837 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1838 orntNew[2] = ornt[2]; 1839 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1840 orntNew[3] = 0; 1841 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1842 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1843 #if 1 1844 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); 1845 for (p = 0; p < 4; ++p) { 1846 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); 1847 } 1848 #endif 1849 /* D quad */ 1850 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1851 orntNew[0] = 0; 1852 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1853 orntNew[1] = -2; 1854 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1855 orntNew[2] = ornt[2]; 1856 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1857 orntNew[3] = ornt[3]; 1858 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1859 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1860 #if 1 1861 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); 1862 for (p = 0; p < 4; ++p) { 1863 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); 1864 } 1865 #endif 1866 } 1867 /* Split faces have 2 vertices and the same cells as the parent */ 1868 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1869 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1870 for (f = fStart; f < fEnd; ++f) { 1871 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1872 1873 for (r = 0; r < 2; ++r) { 1874 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1875 const PetscInt *cone, *ornt, *support; 1876 PetscInt coneNew[2], coneSize, c, supportSize, s; 1877 1878 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1879 coneNew[0] = vStartNew + (cone[0] - vStart); 1880 coneNew[1] = vStartNew + (cone[1] - vStart); 1881 coneNew[(r+1)%2] = newv; 1882 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1883 #if 1 1884 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1885 for (p = 0; p < 2; ++p) { 1886 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); 1887 } 1888 #endif 1889 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1890 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1891 for (s = 0; s < supportSize; ++s) { 1892 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1893 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1894 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1895 for (c = 0; c < coneSize; ++c) { 1896 if (cone[c] == f) break; 1897 } 1898 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1899 } 1900 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1901 #if 1 1902 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1903 for (p = 0; p < supportSize; ++p) { 1904 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); 1905 } 1906 #endif 1907 } 1908 } 1909 /* Interior faces have 2 vertices and 2 cells */ 1910 for (c = cStart; c < cEnd; ++c) { 1911 const PetscInt *cone; 1912 PetscInt coneNew[2], supportNew[2]; 1913 1914 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1915 for (r = 0; r < 4; ++r) { 1916 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1917 1918 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1919 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1920 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1921 #if 1 1922 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1923 for (p = 0; p < 2; ++p) { 1924 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); 1925 } 1926 #endif 1927 supportNew[0] = (c - cStart)*4 + r; 1928 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1929 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1930 #if 1 1931 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1932 for (p = 0; p < 2; ++p) { 1933 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); 1934 } 1935 #endif 1936 } 1937 } 1938 /* Old vertices have identical supports */ 1939 for (v = vStart; v < vEnd; ++v) { 1940 const PetscInt newp = vStartNew + (v - vStart); 1941 const PetscInt *support, *cone; 1942 PetscInt size, s; 1943 1944 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1945 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1946 for (s = 0; s < size; ++s) { 1947 PetscInt r = 0; 1948 1949 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1950 if (cone[1] == v) r = 1; 1951 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1952 } 1953 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1954 #if 1 1955 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1956 for (p = 0; p < size; ++p) { 1957 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); 1958 } 1959 #endif 1960 } 1961 /* Face vertices have 2 + cells supports */ 1962 for (f = fStart; f < fEnd; ++f) { 1963 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1964 const PetscInt *cone, *support; 1965 PetscInt size, s; 1966 1967 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1968 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1969 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1970 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1971 for (s = 0; s < size; ++s) { 1972 PetscInt r = 0; 1973 1974 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1975 if (cone[1] == f) r = 1; 1976 else if (cone[2] == f) r = 2; 1977 else if (cone[3] == f) r = 3; 1978 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1979 } 1980 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1981 #if 1 1982 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1983 for (p = 0; p < 2+size; ++p) { 1984 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); 1985 } 1986 #endif 1987 } 1988 /* Cell vertices have 4 supports */ 1989 for (c = cStart; c < cEnd; ++c) { 1990 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1991 PetscInt supportNew[4]; 1992 1993 for (r = 0; r < 4; ++r) { 1994 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1995 } 1996 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1997 } 1998 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1999 break; 2000 case REFINER_HYBRID_SIMPLEX_2D: 2001 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2002 cMax = PetscMin(cEnd, cMax); 2003 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2004 fMax = PetscMin(fEnd, fMax); 2005 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2006 /* Interior cells have 3 faces */ 2007 for (c = cStart; c < cMax; ++c) { 2008 const PetscInt newp = cStartNew + (c - cStart)*4; 2009 const PetscInt *cone, *ornt; 2010 PetscInt coneNew[3], orntNew[3]; 2011 2012 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2013 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2014 /* A triangle */ 2015 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2016 orntNew[0] = ornt[0]; 2017 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2018 orntNew[1] = -2; 2019 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2020 orntNew[2] = ornt[2]; 2021 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2022 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2023 #if 1 2024 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); 2025 for (p = 0; p < 3; ++p) { 2026 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); 2027 } 2028 #endif 2029 /* B triangle */ 2030 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2031 orntNew[0] = ornt[0]; 2032 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2033 orntNew[1] = ornt[1]; 2034 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2035 orntNew[2] = -2; 2036 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2037 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2038 #if 1 2039 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); 2040 for (p = 0; p < 3; ++p) { 2041 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); 2042 } 2043 #endif 2044 /* C triangle */ 2045 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2046 orntNew[0] = -2; 2047 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2048 orntNew[1] = ornt[1]; 2049 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2050 orntNew[2] = ornt[2]; 2051 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2052 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2053 #if 1 2054 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); 2055 for (p = 0; p < 3; ++p) { 2056 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); 2057 } 2058 #endif 2059 /* D triangle */ 2060 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2061 orntNew[0] = 0; 2062 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2063 orntNew[1] = 0; 2064 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2065 orntNew[2] = 0; 2066 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2067 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2068 #if 1 2069 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); 2070 for (p = 0; p < 3; ++p) { 2071 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); 2072 } 2073 #endif 2074 } 2075 /* 2076 2----3----3 2077 | | 2078 | B | 2079 | | 2080 0----4--- 1 2081 | | 2082 | A | 2083 | | 2084 0----2----1 2085 */ 2086 /* Hybrid cells have 4 faces */ 2087 for (c = cMax; c < cEnd; ++c) { 2088 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2089 const PetscInt *cone, *ornt; 2090 PetscInt coneNew[4], orntNew[4], r; 2091 2092 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2093 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2094 r = (ornt[0] < 0 ? 1 : 0); 2095 /* A quad */ 2096 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2097 orntNew[0] = ornt[0]; 2098 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2099 orntNew[1] = ornt[1]; 2100 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2101 orntNew[2+r] = 0; 2102 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2103 orntNew[3-r] = 0; 2104 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2105 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2106 #if 1 2107 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); 2108 for (p = 0; p < 4; ++p) { 2109 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); 2110 } 2111 #endif 2112 /* B quad */ 2113 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2114 orntNew[0] = ornt[0]; 2115 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2116 orntNew[1] = ornt[1]; 2117 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2118 orntNew[2+r] = 0; 2119 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2120 orntNew[3-r] = 0; 2121 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2122 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2123 #if 1 2124 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); 2125 for (p = 0; p < 4; ++p) { 2126 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); 2127 } 2128 #endif 2129 } 2130 /* Interior split faces have 2 vertices and the same cells as the parent */ 2131 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2132 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2133 for (f = fStart; f < fMax; ++f) { 2134 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2135 2136 for (r = 0; r < 2; ++r) { 2137 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2138 const PetscInt *cone, *ornt, *support; 2139 PetscInt coneNew[2], coneSize, c, supportSize, s; 2140 2141 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2142 coneNew[0] = vStartNew + (cone[0] - vStart); 2143 coneNew[1] = vStartNew + (cone[1] - vStart); 2144 coneNew[(r+1)%2] = newv; 2145 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2146 #if 1 2147 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2148 for (p = 0; p < 2; ++p) { 2149 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); 2150 } 2151 #endif 2152 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2153 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2154 for (s = 0; s < supportSize; ++s) { 2155 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2156 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2157 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2158 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2159 if (support[s] >= cMax) { 2160 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2161 } else { 2162 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2163 } 2164 } 2165 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2166 #if 1 2167 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2168 for (p = 0; p < supportSize; ++p) { 2169 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); 2170 } 2171 #endif 2172 } 2173 } 2174 /* Interior cell faces have 2 vertices and 2 cells */ 2175 for (c = cStart; c < cMax; ++c) { 2176 const PetscInt *cone; 2177 2178 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2179 for (r = 0; r < 3; ++r) { 2180 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 2181 PetscInt coneNew[2]; 2182 PetscInt supportNew[2]; 2183 2184 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2185 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 2186 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2187 #if 1 2188 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2189 for (p = 0; p < 2; ++p) { 2190 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); 2191 } 2192 #endif 2193 supportNew[0] = (c - cStart)*4 + (r+1)%3; 2194 supportNew[1] = (c - cStart)*4 + 3; 2195 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2196 #if 1 2197 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2198 for (p = 0; p < 2; ++p) { 2199 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); 2200 } 2201 #endif 2202 } 2203 } 2204 /* Interior hybrid faces have 2 vertices and the same cells */ 2205 for (f = fMax; f < fEnd; ++f) { 2206 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 2207 const PetscInt *cone, *ornt; 2208 const PetscInt *support; 2209 PetscInt coneNew[2]; 2210 PetscInt supportNew[2]; 2211 PetscInt size, s, r; 2212 2213 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2214 coneNew[0] = vStartNew + (cone[0] - vStart); 2215 coneNew[1] = vStartNew + (cone[1] - vStart); 2216 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2217 #if 1 2218 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2219 for (p = 0; p < 2; ++p) { 2220 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); 2221 } 2222 #endif 2223 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2224 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2225 for (s = 0; s < size; ++s) { 2226 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2227 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2228 for (r = 0; r < 2; ++r) { 2229 if (cone[r+2] == f) break; 2230 } 2231 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 2232 } 2233 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2234 #if 1 2235 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2236 for (p = 0; p < size; ++p) { 2237 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); 2238 } 2239 #endif 2240 } 2241 /* Cell hybrid faces have 2 vertices and 2 cells */ 2242 for (c = cMax; c < cEnd; ++c) { 2243 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2244 const PetscInt *cone; 2245 PetscInt coneNew[2]; 2246 PetscInt supportNew[2]; 2247 2248 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2249 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2250 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2251 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2252 #if 1 2253 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2254 for (p = 0; p < 2; ++p) { 2255 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); 2256 } 2257 #endif 2258 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2259 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2260 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2261 #if 1 2262 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2263 for (p = 0; p < 2; ++p) { 2264 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); 2265 } 2266 #endif 2267 } 2268 /* Old vertices have identical supports */ 2269 for (v = vStart; v < vEnd; ++v) { 2270 const PetscInt newp = vStartNew + (v - vStart); 2271 const PetscInt *support, *cone; 2272 PetscInt size, s; 2273 2274 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2275 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2276 for (s = 0; s < size; ++s) { 2277 if (support[s] >= fMax) { 2278 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 2279 } else { 2280 PetscInt r = 0; 2281 2282 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2283 if (cone[1] == v) r = 1; 2284 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2285 } 2286 } 2287 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2288 #if 1 2289 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2290 for (p = 0; p < size; ++p) { 2291 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); 2292 } 2293 #endif 2294 } 2295 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 2296 for (f = fStart; f < fMax; ++f) { 2297 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2298 const PetscInt *cone, *support; 2299 PetscInt size, newSize = 2, s; 2300 2301 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2302 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2303 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2304 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2305 for (s = 0; s < size; ++s) { 2306 PetscInt r = 0; 2307 2308 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2309 if (support[s] >= cMax) { 2310 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 2311 2312 newSize += 1; 2313 } else { 2314 if (cone[1] == f) r = 1; 2315 else if (cone[2] == f) r = 2; 2316 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 2317 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 2318 2319 newSize += 2; 2320 } 2321 } 2322 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2323 #if 1 2324 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2325 for (p = 0; p < newSize; ++p) { 2326 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); 2327 } 2328 #endif 2329 } 2330 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2331 break; 2332 case REFINER_HYBRID_HEX_2D: 2333 /* Hybrid Hex 2D */ 2334 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2335 cMax = PetscMin(cEnd, cMax); 2336 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2337 fMax = PetscMin(fEnd, fMax); 2338 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2339 /* Interior cells have 4 faces */ 2340 for (c = cStart; c < cMax; ++c) { 2341 const PetscInt newp = cStartNew + (c - cStart)*4; 2342 const PetscInt *cone, *ornt; 2343 PetscInt coneNew[4], orntNew[4]; 2344 2345 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2346 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2347 /* A quad */ 2348 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2349 orntNew[0] = ornt[0]; 2350 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 2351 orntNew[1] = 0; 2352 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2353 orntNew[2] = -2; 2354 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2355 orntNew[3] = ornt[3]; 2356 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2357 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2358 #if 1 2359 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); 2360 for (p = 0; p < 4; ++p) { 2361 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); 2362 } 2363 #endif 2364 /* B quad */ 2365 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2366 orntNew[0] = ornt[0]; 2367 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2368 orntNew[1] = ornt[1]; 2369 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2370 orntNew[2] = 0; 2371 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 2372 orntNew[3] = -2; 2373 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2374 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2375 #if 1 2376 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); 2377 for (p = 0; p < 4; ++p) { 2378 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); 2379 } 2380 #endif 2381 /* C quad */ 2382 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2383 orntNew[0] = -2; 2384 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2385 orntNew[1] = ornt[1]; 2386 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2387 orntNew[2] = ornt[2]; 2388 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2389 orntNew[3] = 0; 2390 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2391 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2392 #if 1 2393 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); 2394 for (p = 0; p < 4; ++p) { 2395 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); 2396 } 2397 #endif 2398 /* D quad */ 2399 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2400 orntNew[0] = 0; 2401 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2402 orntNew[1] = -2; 2403 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2404 orntNew[2] = ornt[2]; 2405 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2406 orntNew[3] = ornt[3]; 2407 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2408 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2409 #if 1 2410 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); 2411 for (p = 0; p < 4; ++p) { 2412 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); 2413 } 2414 #endif 2415 } 2416 /* 2417 2----3----3 2418 | | 2419 | B | 2420 | | 2421 0----4--- 1 2422 | | 2423 | A | 2424 | | 2425 0----2----1 2426 */ 2427 /* Hybrid cells have 4 faces */ 2428 for (c = cMax; c < cEnd; ++c) { 2429 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2430 const PetscInt *cone, *ornt; 2431 PetscInt coneNew[4], orntNew[4]; 2432 2433 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2434 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2435 /* A quad */ 2436 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2437 orntNew[0] = ornt[0]; 2438 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2439 orntNew[1] = ornt[1]; 2440 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 2441 orntNew[2] = 0; 2442 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2443 orntNew[3] = 0; 2444 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2445 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2446 #if 1 2447 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); 2448 for (p = 0; p < 4; ++p) { 2449 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); 2450 } 2451 #endif 2452 /* B quad */ 2453 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2454 orntNew[0] = ornt[0]; 2455 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2456 orntNew[1] = ornt[1]; 2457 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2458 orntNew[2] = 0; 2459 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 2460 orntNew[3] = 0; 2461 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2462 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2463 #if 1 2464 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); 2465 for (p = 0; p < 4; ++p) { 2466 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); 2467 } 2468 #endif 2469 } 2470 /* Interior split faces have 2 vertices and the same cells as the parent */ 2471 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2472 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2473 for (f = fStart; f < fMax; ++f) { 2474 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2475 2476 for (r = 0; r < 2; ++r) { 2477 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2478 const PetscInt *cone, *ornt, *support; 2479 PetscInt coneNew[2], coneSize, c, supportSize, s; 2480 2481 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2482 coneNew[0] = vStartNew + (cone[0] - vStart); 2483 coneNew[1] = vStartNew + (cone[1] - vStart); 2484 coneNew[(r+1)%2] = newv; 2485 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2486 #if 1 2487 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2488 for (p = 0; p < 2; ++p) { 2489 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); 2490 } 2491 #endif 2492 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2493 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2494 for (s = 0; s < supportSize; ++s) { 2495 if (support[s] >= cMax) { 2496 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2497 } else { 2498 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2499 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2500 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2501 for (c = 0; c < coneSize; ++c) { 2502 if (cone[c] == f) break; 2503 } 2504 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2505 } 2506 } 2507 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2508 #if 1 2509 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2510 for (p = 0; p < supportSize; ++p) { 2511 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); 2512 } 2513 #endif 2514 } 2515 } 2516 /* Interior cell faces have 2 vertices and 2 cells */ 2517 for (c = cStart; c < cMax; ++c) { 2518 const PetscInt *cone; 2519 2520 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2521 for (r = 0; r < 4; ++r) { 2522 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2523 PetscInt coneNew[2], supportNew[2]; 2524 2525 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2526 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2527 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2528 #if 1 2529 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2530 for (p = 0; p < 2; ++p) { 2531 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); 2532 } 2533 #endif 2534 supportNew[0] = (c - cStart)*4 + r; 2535 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2536 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2537 #if 1 2538 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2539 for (p = 0; p < 2; ++p) { 2540 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); 2541 } 2542 #endif 2543 } 2544 } 2545 /* Hybrid faces have 2 vertices and the same cells */ 2546 for (f = fMax; f < fEnd; ++f) { 2547 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 2548 const PetscInt *cone, *support; 2549 PetscInt coneNew[2], supportNew[2]; 2550 PetscInt size, s, r; 2551 2552 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2553 coneNew[0] = vStartNew + (cone[0] - vStart); 2554 coneNew[1] = vStartNew + (cone[1] - vStart); 2555 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2556 #if 1 2557 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2558 for (p = 0; p < 2; ++p) { 2559 if ((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); 2560 } 2561 #endif 2562 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2563 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2564 for (s = 0; s < size; ++s) { 2565 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2566 for (r = 0; r < 2; ++r) { 2567 if (cone[r+2] == f) break; 2568 } 2569 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2570 } 2571 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2572 #if 1 2573 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2574 for (p = 0; p < size; ++p) { 2575 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); 2576 } 2577 #endif 2578 } 2579 /* Cell hybrid faces have 2 vertices and 2 cells */ 2580 for (c = cMax; c < cEnd; ++c) { 2581 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2582 const PetscInt *cone; 2583 PetscInt coneNew[2], supportNew[2]; 2584 2585 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2586 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2587 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2588 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2589 #if 1 2590 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2591 for (p = 0; p < 2; ++p) { 2592 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); 2593 } 2594 #endif 2595 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2596 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2597 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2598 #if 1 2599 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2600 for (p = 0; p < 2; ++p) { 2601 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); 2602 } 2603 #endif 2604 } 2605 /* Old vertices have identical supports */ 2606 for (v = vStart; v < vEnd; ++v) { 2607 const PetscInt newp = vStartNew + (v - vStart); 2608 const PetscInt *support, *cone; 2609 PetscInt size, s; 2610 2611 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2612 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2613 for (s = 0; s < size; ++s) { 2614 if (support[s] >= fMax) { 2615 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2616 } else { 2617 PetscInt r = 0; 2618 2619 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2620 if (cone[1] == v) r = 1; 2621 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2622 } 2623 } 2624 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2625 #if 1 2626 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2627 for (p = 0; p < size; ++p) { 2628 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); 2629 } 2630 #endif 2631 } 2632 /* Face vertices have 2 + cells supports */ 2633 for (f = fStart; f < fMax; ++f) { 2634 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2635 const PetscInt *cone, *support; 2636 PetscInt size, s; 2637 2638 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2639 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2640 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2641 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2642 for (s = 0; s < size; ++s) { 2643 PetscInt r = 0; 2644 2645 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2646 if (support[s] >= cMax) { 2647 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2648 } else { 2649 if (cone[1] == f) r = 1; 2650 else if (cone[2] == f) r = 2; 2651 else if (cone[3] == f) r = 3; 2652 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2653 } 2654 } 2655 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2656 #if 1 2657 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2658 for (p = 0; p < 2+size; ++p) { 2659 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); 2660 } 2661 #endif 2662 } 2663 /* Cell vertices have 4 supports */ 2664 for (c = cStart; c < cMax; ++c) { 2665 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2666 PetscInt supportNew[4]; 2667 2668 for (r = 0; r < 4; ++r) { 2669 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2670 } 2671 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2672 } 2673 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2674 break; 2675 case REFINER_SIMPLEX_3D: 2676 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2677 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2678 for (c = cStart; c < cEnd; ++c) { 2679 const PetscInt newp = cStartNew + (c - cStart)*8; 2680 const PetscInt *cone, *ornt; 2681 PetscInt coneNew[4], orntNew[4]; 2682 2683 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2684 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2685 /* A tetrahedron: {0, a, c, d} */ 2686 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2687 orntNew[0] = ornt[0]; 2688 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2689 orntNew[1] = ornt[1]; 2690 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2691 orntNew[2] = ornt[2]; 2692 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2693 orntNew[3] = 0; 2694 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2695 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2696 #if 1 2697 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); 2698 for (p = 0; p < 4; ++p) { 2699 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); 2700 } 2701 #endif 2702 /* B tetrahedron: {a, 1, b, e} */ 2703 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2704 orntNew[0] = ornt[0]; 2705 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2706 orntNew[1] = ornt[1]; 2707 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2708 orntNew[2] = 0; 2709 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2710 orntNew[3] = ornt[3]; 2711 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2712 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2713 #if 1 2714 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); 2715 for (p = 0; p < 4; ++p) { 2716 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); 2717 } 2718 #endif 2719 /* C tetrahedron: {c, b, 2, f} */ 2720 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2721 orntNew[0] = ornt[0]; 2722 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2723 orntNew[1] = 0; 2724 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2725 orntNew[2] = ornt[2]; 2726 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2727 orntNew[3] = ornt[3]; 2728 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2729 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2730 #if 1 2731 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); 2732 for (p = 0; p < 4; ++p) { 2733 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); 2734 } 2735 #endif 2736 /* D tetrahedron: {d, e, f, 3} */ 2737 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2738 orntNew[0] = 0; 2739 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2740 orntNew[1] = ornt[1]; 2741 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2742 orntNew[2] = ornt[2]; 2743 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2744 orntNew[3] = ornt[3]; 2745 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2746 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2747 #if 1 2748 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); 2749 for (p = 0; p < 4; ++p) { 2750 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); 2751 } 2752 #endif 2753 /* A' tetrahedron: {c, d, a, f} */ 2754 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2755 orntNew[0] = -3; 2756 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2757 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 2758 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2759 orntNew[2] = 0; 2760 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2761 orntNew[3] = 2; 2762 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2763 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2764 #if 1 2765 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); 2766 for (p = 0; p < 4; ++p) { 2767 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); 2768 } 2769 #endif 2770 /* B' tetrahedron: {e, b, a, f} */ 2771 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2772 orntNew[0] = -2; 2773 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 2774 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 2775 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2776 orntNew[2] = 0; 2777 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2778 orntNew[3] = 0; 2779 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2780 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2781 #if 1 2782 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); 2783 for (p = 0; p < 4; ++p) { 2784 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); 2785 } 2786 #endif 2787 /* C' tetrahedron: {f, a, c, b} */ 2788 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2789 orntNew[0] = -2; 2790 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2791 orntNew[1] = -2; 2792 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2793 orntNew[2] = -1; 2794 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 2795 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 2796 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2797 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2798 #if 1 2799 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); 2800 for (p = 0; p < 4; ++p) { 2801 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); 2802 } 2803 #endif 2804 /* D' tetrahedron: {f, a, e, d} */ 2805 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2806 orntNew[0] = -2; 2807 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2808 orntNew[1] = -1; 2809 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2810 orntNew[2] = -2; 2811 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 2812 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 2813 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2814 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2815 #if 1 2816 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); 2817 for (p = 0; p < 4; ++p) { 2818 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); 2819 } 2820 #endif 2821 } 2822 /* Split faces have 3 edges and the same cells as the parent */ 2823 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2824 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2825 for (f = fStart; f < fEnd; ++f) { 2826 const PetscInt newp = fStartNew + (f - fStart)*4; 2827 const PetscInt *cone, *ornt, *support; 2828 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2829 2830 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2831 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2832 /* A triangle */ 2833 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2834 orntNew[0] = ornt[0]; 2835 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2836 orntNew[1] = -2; 2837 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2838 orntNew[2] = ornt[2]; 2839 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2840 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2841 #if 1 2842 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); 2843 for (p = 0; p < 3; ++p) { 2844 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); 2845 } 2846 #endif 2847 /* B triangle */ 2848 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2849 orntNew[0] = ornt[0]; 2850 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2851 orntNew[1] = ornt[1]; 2852 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2853 orntNew[2] = -2; 2854 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2855 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2856 #if 1 2857 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); 2858 for (p = 0; p < 3; ++p) { 2859 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); 2860 } 2861 #endif 2862 /* C triangle */ 2863 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2864 orntNew[0] = -2; 2865 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2866 orntNew[1] = ornt[1]; 2867 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2868 orntNew[2] = ornt[2]; 2869 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2870 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2871 #if 1 2872 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); 2873 for (p = 0; p < 3; ++p) { 2874 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); 2875 } 2876 #endif 2877 /* D triangle */ 2878 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2879 orntNew[0] = 0; 2880 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2881 orntNew[1] = 0; 2882 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2883 orntNew[2] = 0; 2884 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2885 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2886 #if 1 2887 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); 2888 for (p = 0; p < 3; ++p) { 2889 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); 2890 } 2891 #endif 2892 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2893 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2894 for (r = 0; r < 4; ++r) { 2895 for (s = 0; s < supportSize; ++s) { 2896 PetscInt subf; 2897 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2898 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2899 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2900 for (c = 0; c < coneSize; ++c) { 2901 if (cone[c] == f) break; 2902 } 2903 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2904 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2905 } 2906 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2907 #if 1 2908 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); 2909 for (p = 0; p < supportSize; ++p) { 2910 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); 2911 } 2912 #endif 2913 } 2914 } 2915 /* Interior faces have 3 edges and 2 cells */ 2916 for (c = cStart; c < cEnd; ++c) { 2917 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2918 const PetscInt *cone, *ornt; 2919 PetscInt coneNew[3], orntNew[3]; 2920 PetscInt supportNew[2]; 2921 2922 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2923 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2924 /* Face A: {c, a, d} */ 2925 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 2926 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2927 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 2928 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2929 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 2930 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2931 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2932 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2933 #if 1 2934 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2935 for (p = 0; p < 3; ++p) { 2936 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); 2937 } 2938 #endif 2939 supportNew[0] = (c - cStart)*8 + 0; 2940 supportNew[1] = (c - cStart)*8 + 0+4; 2941 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2942 #if 1 2943 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2944 for (p = 0; p < 2; ++p) { 2945 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); 2946 } 2947 #endif 2948 ++newp; 2949 /* Face B: {a, b, e} */ 2950 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 2951 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2952 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 2953 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2954 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 2955 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2956 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2957 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2958 #if 1 2959 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2960 for (p = 0; p < 3; ++p) { 2961 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); 2962 } 2963 #endif 2964 supportNew[0] = (c - cStart)*8 + 1; 2965 supportNew[1] = (c - cStart)*8 + 1+4; 2966 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2967 #if 1 2968 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2969 for (p = 0; p < 2; ++p) { 2970 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); 2971 } 2972 #endif 2973 ++newp; 2974 /* Face C: {c, f, b} */ 2975 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 2976 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2977 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 2978 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2979 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 2980 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2981 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2982 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2983 #if 1 2984 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2985 for (p = 0; p < 3; ++p) { 2986 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); 2987 } 2988 #endif 2989 supportNew[0] = (c - cStart)*8 + 2; 2990 supportNew[1] = (c - cStart)*8 + 2+4; 2991 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2992 #if 1 2993 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2994 for (p = 0; p < 2; ++p) { 2995 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); 2996 } 2997 #endif 2998 ++newp; 2999 /* Face D: {d, e, f} */ 3000 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3001 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3002 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3003 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3004 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3005 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3006 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3007 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3008 #if 1 3009 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3010 for (p = 0; p < 3; ++p) { 3011 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); 3012 } 3013 #endif 3014 supportNew[0] = (c - cStart)*8 + 3; 3015 supportNew[1] = (c - cStart)*8 + 3+4; 3016 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3017 #if 1 3018 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3019 for (p = 0; p < 2; ++p) { 3020 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); 3021 } 3022 #endif 3023 ++newp; 3024 /* Face E: {d, f, a} */ 3025 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3026 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3027 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3028 orntNew[1] = -2; 3029 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3030 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3031 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3032 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3033 #if 1 3034 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3035 for (p = 0; p < 3; ++p) { 3036 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); 3037 } 3038 #endif 3039 supportNew[0] = (c - cStart)*8 + 0+4; 3040 supportNew[1] = (c - cStart)*8 + 3+4; 3041 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3042 #if 1 3043 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3044 for (p = 0; p < 2; ++p) { 3045 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); 3046 } 3047 #endif 3048 ++newp; 3049 /* Face F: {c, a, f} */ 3050 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3051 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3052 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3053 orntNew[1] = 0; 3054 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3055 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3056 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3057 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3058 #if 1 3059 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3060 for (p = 0; p < 3; ++p) { 3061 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); 3062 } 3063 #endif 3064 supportNew[0] = (c - cStart)*8 + 0+4; 3065 supportNew[1] = (c - cStart)*8 + 2+4; 3066 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3067 #if 1 3068 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3069 for (p = 0; p < 2; ++p) { 3070 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); 3071 } 3072 #endif 3073 ++newp; 3074 /* Face G: {e, a, f} */ 3075 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3076 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3077 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3078 orntNew[1] = 0; 3079 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3080 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3081 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3082 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3083 #if 1 3084 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3085 for (p = 0; p < 3; ++p) { 3086 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); 3087 } 3088 #endif 3089 supportNew[0] = (c - cStart)*8 + 1+4; 3090 supportNew[1] = (c - cStart)*8 + 3+4; 3091 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3092 #if 1 3093 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3094 for (p = 0; p < 2; ++p) { 3095 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); 3096 } 3097 #endif 3098 ++newp; 3099 /* Face H: {a, b, f} */ 3100 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3101 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3102 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3103 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3104 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3105 orntNew[2] = -2; 3106 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3107 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3108 #if 1 3109 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3110 for (p = 0; p < 3; ++p) { 3111 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); 3112 } 3113 #endif 3114 supportNew[0] = (c - cStart)*8 + 1+4; 3115 supportNew[1] = (c - cStart)*8 + 2+4; 3116 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3117 #if 1 3118 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3119 for (p = 0; p < 2; ++p) { 3120 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); 3121 } 3122 #endif 3123 ++newp; 3124 } 3125 /* Split Edges have 2 vertices and the same faces as the parent */ 3126 for (e = eStart; e < eEnd; ++e) { 3127 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3128 3129 for (r = 0; r < 2; ++r) { 3130 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3131 const PetscInt *cone, *ornt, *support; 3132 PetscInt coneNew[2], coneSize, c, supportSize, s; 3133 3134 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3135 coneNew[0] = vStartNew + (cone[0] - vStart); 3136 coneNew[1] = vStartNew + (cone[1] - vStart); 3137 coneNew[(r+1)%2] = newv; 3138 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3139 #if 1 3140 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3141 for (p = 0; p < 2; ++p) { 3142 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); 3143 } 3144 #endif 3145 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3146 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3147 for (s = 0; s < supportSize; ++s) { 3148 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3149 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3150 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3151 for (c = 0; c < coneSize; ++c) { 3152 if (cone[c] == e) break; 3153 } 3154 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3155 } 3156 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3157 #if 1 3158 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3159 for (p = 0; p < supportSize; ++p) { 3160 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); 3161 } 3162 #endif 3163 } 3164 } 3165 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3166 for (f = fStart; f < fEnd; ++f) { 3167 const PetscInt *cone, *ornt, *support; 3168 PetscInt coneSize, supportSize, s; 3169 3170 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3171 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3172 for (r = 0; r < 3; ++r) { 3173 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3174 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3175 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3176 -1, -1, 1, 6, 0, 4, 3177 2, 5, 3, 4, -1, -1, 3178 -1, -1, 3, 6, 2, 7}; 3179 3180 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3181 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3182 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3183 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3184 #if 1 3185 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3186 for (p = 0; p < 2; ++p) { 3187 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); 3188 } 3189 #endif 3190 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3191 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3192 for (s = 0; s < supportSize; ++s) { 3193 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3194 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3195 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3196 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3197 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3198 er = GetTriMidEdgeInverse_Static(ornt[c], r); 3199 if (er == eint[c]) { 3200 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3201 } else { 3202 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3203 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3204 } 3205 } 3206 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3207 #if 1 3208 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3209 for (p = 0; p < intFaces; ++p) { 3210 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); 3211 } 3212 #endif 3213 } 3214 } 3215 /* Interior edges have 2 vertices and 4 faces */ 3216 for (c = cStart; c < cEnd; ++c) { 3217 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3218 const PetscInt *cone, *ornt, *fcone; 3219 PetscInt coneNew[2], supportNew[4], find; 3220 3221 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3222 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3223 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3224 find = GetTriEdge_Static(ornt[0], 0); 3225 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3226 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3227 find = GetTriEdge_Static(ornt[2], 1); 3228 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3229 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3230 #if 1 3231 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3232 for (p = 0; p < 2; ++p) { 3233 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); 3234 } 3235 #endif 3236 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3237 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3238 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3239 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3240 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3241 #if 1 3242 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3243 for (p = 0; p < 4; ++p) { 3244 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); 3245 } 3246 #endif 3247 } 3248 /* Old vertices have identical supports */ 3249 for (v = vStart; v < vEnd; ++v) { 3250 const PetscInt newp = vStartNew + (v - vStart); 3251 const PetscInt *support, *cone; 3252 PetscInt size, s; 3253 3254 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3255 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3256 for (s = 0; s < size; ++s) { 3257 PetscInt r = 0; 3258 3259 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3260 if (cone[1] == v) r = 1; 3261 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3262 } 3263 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3264 #if 1 3265 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3266 for (p = 0; p < size; ++p) { 3267 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); 3268 } 3269 #endif 3270 } 3271 /* Edge vertices have 2 + face*2 + 0/1 supports */ 3272 for (e = eStart; e < eEnd; ++e) { 3273 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3274 const PetscInt *cone, *support; 3275 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 3276 3277 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3278 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3279 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3280 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3281 for (s = 0; s < size; ++s) { 3282 PetscInt r = 0; 3283 3284 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3285 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3286 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3287 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3288 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3289 } 3290 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3291 for (s = 0; s < starSize*2; s += 2) { 3292 const PetscInt *cone, *ornt; 3293 PetscInt e01, e23; 3294 3295 if ((star[s] >= cStart) && (star[s] < cEnd)) { 3296 /* Check edge 0-1 */ 3297 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3298 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3299 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3300 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3301 /* Check edge 2-3 */ 3302 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3303 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3304 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3305 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3306 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 3307 } 3308 } 3309 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3310 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3311 #if 1 3312 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3313 for (p = 0; p < 2+size*2+cellSize; ++p) { 3314 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); 3315 } 3316 #endif 3317 } 3318 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3319 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3320 break; 3321 case REFINER_HYBRID_SIMPLEX_3D: 3322 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 3323 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3324 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3325 for (c = cStart; c < cMax; ++c) { 3326 const PetscInt newp = cStartNew + (c - cStart)*8; 3327 const PetscInt *cone, *ornt; 3328 PetscInt coneNew[4], orntNew[4]; 3329 3330 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3331 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3332 /* A tetrahedron: {0, a, c, d} */ 3333 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3334 orntNew[0] = ornt[0]; 3335 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3336 orntNew[1] = ornt[1]; 3337 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3338 orntNew[2] = ornt[2]; 3339 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3340 orntNew[3] = 0; 3341 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3342 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3343 #if 1 3344 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); 3345 for (p = 0; p < 4; ++p) { 3346 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); 3347 } 3348 #endif 3349 /* B tetrahedron: {a, 1, b, e} */ 3350 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3351 orntNew[0] = ornt[0]; 3352 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3353 orntNew[1] = ornt[1]; 3354 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3355 orntNew[2] = 0; 3356 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3357 orntNew[3] = ornt[3]; 3358 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3359 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3360 #if 1 3361 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); 3362 for (p = 0; p < 4; ++p) { 3363 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); 3364 } 3365 #endif 3366 /* C tetrahedron: {c, b, 2, f} */ 3367 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3368 orntNew[0] = ornt[0]; 3369 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3370 orntNew[1] = 0; 3371 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3372 orntNew[2] = ornt[2]; 3373 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3374 orntNew[3] = ornt[3]; 3375 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3376 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3377 #if 1 3378 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); 3379 for (p = 0; p < 4; ++p) { 3380 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); 3381 } 3382 #endif 3383 /* D tetrahedron: {d, e, f, 3} */ 3384 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3385 orntNew[0] = 0; 3386 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3387 orntNew[1] = ornt[1]; 3388 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3389 orntNew[2] = ornt[2]; 3390 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3391 orntNew[3] = ornt[3]; 3392 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3393 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3394 #if 1 3395 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); 3396 for (p = 0; p < 4; ++p) { 3397 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); 3398 } 3399 #endif 3400 /* A' tetrahedron: {d, a, c, f} */ 3401 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3402 orntNew[0] = -3; 3403 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3404 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3405 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3406 orntNew[2] = 0; 3407 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3408 orntNew[3] = 2; 3409 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3410 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3411 #if 1 3412 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); 3413 for (p = 0; p < 4; ++p) { 3414 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); 3415 } 3416 #endif 3417 /* B' tetrahedron: {e, b, a, f} */ 3418 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3419 orntNew[0] = -3; 3420 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3421 orntNew[1] = 1; 3422 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3423 orntNew[2] = 0; 3424 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 3425 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 3426 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3427 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3428 #if 1 3429 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); 3430 for (p = 0; p < 4; ++p) { 3431 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); 3432 } 3433 #endif 3434 /* C' tetrahedron: {b, f, c, a} */ 3435 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3436 orntNew[0] = -3; 3437 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 3438 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3439 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3440 orntNew[2] = -3; 3441 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3442 orntNew[3] = -2; 3443 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3444 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3445 #if 1 3446 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); 3447 for (p = 0; p < 4; ++p) { 3448 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); 3449 } 3450 #endif 3451 /* D' tetrahedron: {f, e, d, a} */ 3452 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3453 orntNew[0] = -3; 3454 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3455 orntNew[1] = -3; 3456 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 3457 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 3458 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3459 orntNew[3] = -3; 3460 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3461 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3462 #if 1 3463 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); 3464 for (p = 0; p < 4; ++p) { 3465 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); 3466 } 3467 #endif 3468 } 3469 /* Hybrid cells have 5 faces */ 3470 for (c = cMax; c < cEnd; ++c) { 3471 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 3472 const PetscInt *cone, *ornt, *fornt; 3473 PetscInt coneNew[5], orntNew[5], o, of, i; 3474 3475 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3476 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3477 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 3478 o = ornt[0] < 0 ? -1 : 1; 3479 for (r = 0; r < 3; ++r) { 3480 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 3481 orntNew[0] = ornt[0]; 3482 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 3483 orntNew[1] = ornt[1]; 3484 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 3485 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 3486 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 3487 orntNew[i] = 0; 3488 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 3489 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 3490 orntNew[i] = 0; 3491 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 3492 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 3493 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); 3494 orntNew[i] = 0; 3495 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3496 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3497 #if 1 3498 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); 3499 for (p = 0; p < 2; ++p) { 3500 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); 3501 } 3502 for (p = 2; p < 5; ++p) { 3503 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); 3504 } 3505 #endif 3506 } 3507 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 3508 orntNew[0] = 0; 3509 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3510 orntNew[1] = 0; 3511 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3512 orntNew[2] = 0; 3513 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3514 orntNew[3] = 0; 3515 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3516 orntNew[4] = 0; 3517 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3518 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3519 #if 1 3520 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); 3521 for (p = 0; p < 2; ++p) { 3522 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); 3523 } 3524 for (p = 2; p < 5; ++p) { 3525 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); 3526 } 3527 #endif 3528 } 3529 /* Split faces have 3 edges and the same cells as the parent */ 3530 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3531 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3532 for (f = fStart; f < fMax; ++f) { 3533 const PetscInt newp = fStartNew + (f - fStart)*4; 3534 const PetscInt *cone, *ornt, *support; 3535 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3536 3537 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3538 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3539 /* A triangle */ 3540 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3541 orntNew[0] = ornt[0]; 3542 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3543 orntNew[1] = -2; 3544 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3545 orntNew[2] = ornt[2]; 3546 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3547 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3548 #if 1 3549 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); 3550 for (p = 0; p < 3; ++p) { 3551 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); 3552 } 3553 #endif 3554 /* B triangle */ 3555 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3556 orntNew[0] = ornt[0]; 3557 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3558 orntNew[1] = ornt[1]; 3559 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3560 orntNew[2] = -2; 3561 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3562 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3563 #if 1 3564 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); 3565 for (p = 0; p < 3; ++p) { 3566 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); 3567 } 3568 #endif 3569 /* C triangle */ 3570 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3571 orntNew[0] = -2; 3572 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3573 orntNew[1] = ornt[1]; 3574 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3575 orntNew[2] = ornt[2]; 3576 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3577 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3578 #if 1 3579 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); 3580 for (p = 0; p < 3; ++p) { 3581 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); 3582 } 3583 #endif 3584 /* D triangle */ 3585 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3586 orntNew[0] = 0; 3587 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3588 orntNew[1] = 0; 3589 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3590 orntNew[2] = 0; 3591 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3592 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3593 #if 1 3594 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); 3595 for (p = 0; p < 3; ++p) { 3596 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); 3597 } 3598 #endif 3599 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3600 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3601 for (r = 0; r < 4; ++r) { 3602 for (s = 0; s < supportSize; ++s) { 3603 PetscInt subf; 3604 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3605 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3606 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3607 for (c = 0; c < coneSize; ++c) { 3608 if (cone[c] == f) break; 3609 } 3610 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3611 if (support[s] < cMax) { 3612 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3613 } else { 3614 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3615 } 3616 } 3617 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3618 #if 1 3619 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); 3620 for (p = 0; p < supportSize; ++p) { 3621 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); 3622 } 3623 #endif 3624 } 3625 } 3626 /* Interior cell faces have 3 edges and 2 cells */ 3627 for (c = cStart; c < cMax; ++c) { 3628 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3629 const PetscInt *cone, *ornt; 3630 PetscInt coneNew[3], orntNew[3]; 3631 PetscInt supportNew[2]; 3632 3633 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3634 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3635 /* Face A: {c, a, d} */ 3636 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3637 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3638 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3639 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3640 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3641 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3642 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3643 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3644 #if 1 3645 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3646 for (p = 0; p < 3; ++p) { 3647 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); 3648 } 3649 #endif 3650 supportNew[0] = (c - cStart)*8 + 0; 3651 supportNew[1] = (c - cStart)*8 + 0+4; 3652 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3653 #if 1 3654 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3655 for (p = 0; p < 2; ++p) { 3656 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); 3657 } 3658 #endif 3659 ++newp; 3660 /* Face B: {a, b, e} */ 3661 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3662 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3663 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3664 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3665 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3666 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3667 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3668 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3669 #if 1 3670 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); 3671 for (p = 0; p < 3; ++p) { 3672 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); 3673 } 3674 #endif 3675 supportNew[0] = (c - cStart)*8 + 1; 3676 supportNew[1] = (c - cStart)*8 + 1+4; 3677 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3678 #if 1 3679 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3680 for (p = 0; p < 2; ++p) { 3681 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); 3682 } 3683 #endif 3684 ++newp; 3685 /* Face C: {c, f, b} */ 3686 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3687 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3688 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3689 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3690 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3691 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3692 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3693 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3694 #if 1 3695 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3696 for (p = 0; p < 3; ++p) { 3697 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); 3698 } 3699 #endif 3700 supportNew[0] = (c - cStart)*8 + 2; 3701 supportNew[1] = (c - cStart)*8 + 2+4; 3702 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3703 #if 1 3704 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3705 for (p = 0; p < 2; ++p) { 3706 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); 3707 } 3708 #endif 3709 ++newp; 3710 /* Face D: {d, e, f} */ 3711 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3712 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3713 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3714 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3715 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3716 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3717 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3718 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3719 #if 1 3720 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3721 for (p = 0; p < 3; ++p) { 3722 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); 3723 } 3724 #endif 3725 supportNew[0] = (c - cStart)*8 + 3; 3726 supportNew[1] = (c - cStart)*8 + 3+4; 3727 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3728 #if 1 3729 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3730 for (p = 0; p < 2; ++p) { 3731 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); 3732 } 3733 #endif 3734 ++newp; 3735 /* Face E: {d, f, a} */ 3736 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3737 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3738 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3739 orntNew[1] = -2; 3740 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3741 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3742 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3743 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3744 #if 1 3745 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3746 for (p = 0; p < 3; ++p) { 3747 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); 3748 } 3749 #endif 3750 supportNew[0] = (c - cStart)*8 + 0+4; 3751 supportNew[1] = (c - cStart)*8 + 3+4; 3752 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3753 #if 1 3754 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3755 for (p = 0; p < 2; ++p) { 3756 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); 3757 } 3758 #endif 3759 ++newp; 3760 /* Face F: {c, a, f} */ 3761 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3762 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3763 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3764 orntNew[1] = 0; 3765 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3766 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3767 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3768 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3769 #if 1 3770 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3771 for (p = 0; p < 3; ++p) { 3772 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); 3773 } 3774 #endif 3775 supportNew[0] = (c - cStart)*8 + 0+4; 3776 supportNew[1] = (c - cStart)*8 + 2+4; 3777 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3778 #if 1 3779 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3780 for (p = 0; p < 2; ++p) { 3781 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); 3782 } 3783 #endif 3784 ++newp; 3785 /* Face G: {e, a, f} */ 3786 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3787 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3788 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3789 orntNew[1] = 0; 3790 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3791 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3792 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3793 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3794 #if 1 3795 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3796 for (p = 0; p < 3; ++p) { 3797 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); 3798 } 3799 #endif 3800 supportNew[0] = (c - cStart)*8 + 1+4; 3801 supportNew[1] = (c - cStart)*8 + 3+4; 3802 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3803 #if 1 3804 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3805 for (p = 0; p < 2; ++p) { 3806 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); 3807 } 3808 #endif 3809 ++newp; 3810 /* Face H: {a, b, f} */ 3811 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3812 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3813 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3814 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3815 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3816 orntNew[2] = -2; 3817 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3818 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3819 #if 1 3820 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3821 for (p = 0; p < 3; ++p) { 3822 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); 3823 } 3824 #endif 3825 supportNew[0] = (c - cStart)*8 + 1+4; 3826 supportNew[1] = (c - cStart)*8 + 2+4; 3827 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3828 #if 1 3829 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3830 for (p = 0; p < 2; ++p) { 3831 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); 3832 } 3833 #endif 3834 ++newp; 3835 } 3836 /* Hybrid split faces have 4 edges and same cells */ 3837 for (f = fMax; f < fEnd; ++f) { 3838 const PetscInt *cone, *ornt, *support; 3839 PetscInt coneNew[4], orntNew[4]; 3840 PetscInt supportNew[2], size, s, c; 3841 3842 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3843 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3844 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3845 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3846 for (r = 0; r < 2; ++r) { 3847 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3848 3849 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3850 orntNew[0] = ornt[0]; 3851 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3852 orntNew[1] = ornt[1]; 3853 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3854 orntNew[2+r] = 0; 3855 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3856 orntNew[3-r] = 0; 3857 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3858 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3859 #if 1 3860 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3861 for (p = 0; p < 2; ++p) { 3862 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); 3863 } 3864 for (p = 2; p < 4; ++p) { 3865 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); 3866 } 3867 #endif 3868 for (s = 0; s < size; ++s) { 3869 const PetscInt *coneCell, *orntCell, *fornt; 3870 PetscInt o, of; 3871 3872 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3873 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3874 o = orntCell[0] < 0 ? -1 : 1; 3875 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3876 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3877 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3878 of = fornt[c-2] < 0 ? -1 : 1; 3879 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3880 } 3881 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3882 #if 1 3883 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3884 for (p = 0; p < size; ++p) { 3885 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); 3886 } 3887 #endif 3888 } 3889 } 3890 /* Hybrid cell faces have 4 edges and 2 cells */ 3891 for (c = cMax; c < cEnd; ++c) { 3892 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3893 const PetscInt *cone, *ornt; 3894 PetscInt coneNew[4], orntNew[4]; 3895 PetscInt supportNew[2]; 3896 3897 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3898 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3899 for (r = 0; r < 3; ++r) { 3900 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3901 orntNew[0] = 0; 3902 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3903 orntNew[1] = 0; 3904 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3905 orntNew[2] = 0; 3906 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3907 orntNew[3] = 0; 3908 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3909 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3910 #if 1 3911 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); 3912 for (p = 0; p < 2; ++p) { 3913 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); 3914 } 3915 for (p = 2; p < 4; ++p) { 3916 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); 3917 } 3918 #endif 3919 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3920 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3921 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3922 #if 1 3923 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); 3924 for (p = 0; p < 2; ++p) { 3925 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); 3926 } 3927 #endif 3928 } 3929 } 3930 /* Interior split edges have 2 vertices and the same faces as the parent */ 3931 for (e = eStart; e < eMax; ++e) { 3932 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3933 3934 for (r = 0; r < 2; ++r) { 3935 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3936 const PetscInt *cone, *ornt, *support; 3937 PetscInt coneNew[2], coneSize, c, supportSize, s; 3938 3939 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3940 coneNew[0] = vStartNew + (cone[0] - vStart); 3941 coneNew[1] = vStartNew + (cone[1] - vStart); 3942 coneNew[(r+1)%2] = newv; 3943 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3944 #if 1 3945 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3946 for (p = 0; p < 2; ++p) { 3947 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); 3948 } 3949 #endif 3950 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3951 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3952 for (s = 0; s < supportSize; ++s) { 3953 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3954 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3955 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3956 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3957 if (support[s] < fMax) { 3958 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3959 } else { 3960 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3961 } 3962 } 3963 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3964 #if 1 3965 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3966 for (p = 0; p < supportSize; ++p) { 3967 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); 3968 } 3969 #endif 3970 } 3971 } 3972 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3973 for (f = fStart; f < fMax; ++f) { 3974 const PetscInt *cone, *ornt, *support; 3975 PetscInt coneSize, supportSize, s; 3976 3977 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3978 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3979 for (r = 0; r < 3; ++r) { 3980 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3981 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3982 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3983 -1, -1, 1, 6, 0, 4, 3984 2, 5, 3, 4, -1, -1, 3985 -1, -1, 3, 6, 2, 7}; 3986 3987 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3988 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3989 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3990 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3991 #if 1 3992 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3993 for (p = 0; p < 2; ++p) { 3994 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); 3995 } 3996 #endif 3997 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3998 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3999 for (s = 0; s < supportSize; ++s) { 4000 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4001 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4002 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4003 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4004 if (support[s] < cMax) { 4005 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4006 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4007 if (er == eint[c]) { 4008 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4009 } else { 4010 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4011 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4012 } 4013 } else { 4014 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4015 } 4016 } 4017 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4018 #if 1 4019 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4020 for (p = 0; p < intFaces; ++p) { 4021 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); 4022 } 4023 #endif 4024 } 4025 } 4026 /* Interior cell edges have 2 vertices and 4 faces */ 4027 for (c = cStart; c < cMax; ++c) { 4028 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4029 const PetscInt *cone, *ornt, *fcone; 4030 PetscInt coneNew[2], supportNew[4], find; 4031 4032 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4033 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4034 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4035 find = GetTriEdge_Static(ornt[0], 0); 4036 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4037 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4038 find = GetTriEdge_Static(ornt[2], 1); 4039 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4040 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4041 #if 1 4042 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4043 for (p = 0; p < 2; ++p) { 4044 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); 4045 } 4046 #endif 4047 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4048 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4049 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4050 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4051 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4052 #if 1 4053 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4054 for (p = 0; p < 4; ++p) { 4055 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); 4056 } 4057 #endif 4058 } 4059 /* Hybrid edges have two vertices and the same faces */ 4060 for (e = eMax; e < eEnd; ++e) { 4061 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4062 const PetscInt *cone, *support, *fcone; 4063 PetscInt coneNew[2], size, fsize, s; 4064 4065 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4066 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4067 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4068 coneNew[0] = vStartNew + (cone[0] - vStart); 4069 coneNew[1] = vStartNew + (cone[1] - vStart); 4070 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4071 #if 1 4072 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4073 for (p = 0; p < 2; ++p) { 4074 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); 4075 } 4076 #endif 4077 for (s = 0; s < size; ++s) { 4078 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4079 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4080 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4081 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 4082 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4083 } 4084 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4085 #if 1 4086 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4087 for (p = 0; p < size; ++p) { 4088 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); 4089 } 4090 #endif 4091 } 4092 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4093 for (f = fMax; f < fEnd; ++f) { 4094 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4095 const PetscInt *cone, *support, *ccone, *cornt; 4096 PetscInt coneNew[2], size, csize, s; 4097 4098 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4099 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4100 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4101 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4102 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4103 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4104 #if 1 4105 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4106 for (p = 0; p < 2; ++p) { 4107 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); 4108 } 4109 #endif 4110 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4111 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4112 for (s = 0; s < size; ++s) { 4113 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4114 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4115 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4116 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4117 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]); 4118 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4119 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4120 } 4121 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4122 #if 1 4123 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4124 for (p = 0; p < 2+size*2; ++p) { 4125 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); 4126 } 4127 #endif 4128 } 4129 /* Interior vertices have identical supports */ 4130 for (v = vStart; v < vEnd; ++v) { 4131 const PetscInt newp = vStartNew + (v - vStart); 4132 const PetscInt *support, *cone; 4133 PetscInt size, s; 4134 4135 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4136 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4137 for (s = 0; s < size; ++s) { 4138 PetscInt r = 0; 4139 4140 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4141 if (cone[1] == v) r = 1; 4142 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4143 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4144 } 4145 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4146 #if 1 4147 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4148 for (p = 0; p < size; ++p) { 4149 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); 4150 } 4151 #endif 4152 } 4153 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4154 for (e = eStart; e < eMax; ++e) { 4155 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4156 const PetscInt *cone, *support; 4157 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4158 4159 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4160 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4161 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4162 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4163 for (s = 0; s < size; ++s) { 4164 PetscInt r = 0; 4165 4166 if (support[s] < fMax) { 4167 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4168 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4169 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4170 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4171 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4172 faceSize += 2; 4173 } else { 4174 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4175 ++faceSize; 4176 } 4177 } 4178 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4179 for (s = 0; s < starSize*2; s += 2) { 4180 const PetscInt *cone, *ornt; 4181 PetscInt e01, e23; 4182 4183 if ((star[s] >= cStart) && (star[s] < cMax)) { 4184 /* Check edge 0-1 */ 4185 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4186 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4187 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4188 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4189 /* Check edge 2-3 */ 4190 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4191 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4192 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4193 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4194 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 4195 } 4196 } 4197 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4198 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4199 #if 1 4200 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4201 for (p = 0; p < 2+faceSize+cellSize; ++p) { 4202 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); 4203 } 4204 #endif 4205 } 4206 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4207 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4208 break; 4209 case REFINER_SIMPLEX_TO_HEX_3D: 4210 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4211 /* All cells have 6 faces */ 4212 for (c = cStart; c < cEnd; ++c) { 4213 const PetscInt newp = cStartNew + (c - cStart)*4; 4214 const PetscInt *cone, *ornt; 4215 PetscInt coneNew[6]; 4216 PetscInt orntNew[6]; 4217 4218 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4219 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4220 /* A hex */ 4221 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 4222 orntNew[0] = ornt[0] < 0 ? -1 : 1; 4223 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 4224 orntNew[1] = -4; 4225 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 4226 orntNew[2] = ornt[2] < 0 ? -1 : 1; 4227 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 4228 orntNew[3] = -1; 4229 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 4230 orntNew[4] = 0; 4231 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 4232 orntNew[5] = ornt[1] < 0 ? -1 : 1; 4233 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4234 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4235 #if 1 4236 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); 4237 for (p = 0; p < 6; ++p) { 4238 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); 4239 } 4240 #endif 4241 /* B hex */ 4242 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 4243 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4244 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 4245 orntNew[1] = 0; 4246 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 4247 orntNew[2] = 0; 4248 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 4249 orntNew[3] = ornt[3] < 0 ? -2 : 0; 4250 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 4251 orntNew[4] = 0; 4252 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 4253 orntNew[5] = ornt[1] < 0 ? -4 : 2; 4254 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4255 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4256 #if 1 4257 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); 4258 for (p = 0; p < 6; ++p) { 4259 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); 4260 } 4261 #endif 4262 /* C hex */ 4263 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 4264 orntNew[0] = ornt[0] < 0 ? -4 : 2; 4265 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 4266 orntNew[1] = -4; 4267 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 4268 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4269 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 4270 orntNew[3] = -1; 4271 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 4272 orntNew[4] = ornt[3] < 0 ? -1 : 1; 4273 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 4274 orntNew[5] = -4; 4275 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4276 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4277 #if 1 4278 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); 4279 for (p = 0; p < 6; ++p) { 4280 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); 4281 } 4282 #endif 4283 /* D hex */ 4284 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 4285 orntNew[0] = 0; 4286 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 4287 orntNew[1] = ornt[3] < 0 ? -1 : 1; 4288 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 4289 orntNew[2] = ornt[2] < 0 ? -4 : 2; 4290 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 4291 orntNew[3] = -1; 4292 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 4293 orntNew[4] = 0; 4294 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 4295 orntNew[5] = ornt[1] < 0 ? -2 : 0; 4296 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4297 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4298 #if 1 4299 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); 4300 for (p = 0; p < 6; ++p) { 4301 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); 4302 } 4303 #endif 4304 } 4305 /* Split faces have 4 edges and the same cells as the parent */ 4306 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4307 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4308 for (f = fStart; f < fEnd; ++f) { 4309 const PetscInt newp = fStartNew + (f - fStart)*3; 4310 const PetscInt *cone, *ornt, *support; 4311 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 4312 4313 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4314 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4315 /* A quad */ 4316 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4317 orntNew[0] = ornt[2]; 4318 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4319 orntNew[1] = ornt[0]; 4320 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4321 orntNew[2] = 0; 4322 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4323 orntNew[3] = -2; 4324 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4325 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4326 #if 1 4327 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); 4328 for (p = 0; p < 4; ++p) { 4329 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); 4330 } 4331 #endif 4332 /* B quad */ 4333 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4334 orntNew[0] = ornt[0]; 4335 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4336 orntNew[1] = ornt[1]; 4337 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4338 orntNew[2] = 0; 4339 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4340 orntNew[3] = -2; 4341 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4342 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4343 #if 1 4344 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); 4345 for (p = 0; p < 4; ++p) { 4346 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); 4347 } 4348 #endif 4349 /* C quad */ 4350 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4351 orntNew[0] = ornt[1]; 4352 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4353 orntNew[1] = ornt[2]; 4354 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4355 orntNew[2] = 0; 4356 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4357 orntNew[3] = -2; 4358 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4359 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4360 #if 1 4361 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); 4362 for (p = 0; p < 4; ++p) { 4363 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); 4364 } 4365 #endif 4366 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4367 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4368 for (r = 0; r < 3; ++r) { 4369 for (s = 0; s < supportSize; ++s) { 4370 PetscInt subf; 4371 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4372 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4373 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4374 for (c = 0; c < coneSize; ++c) { 4375 if (cone[c] == f) break; 4376 } 4377 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4378 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 4379 } 4380 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4381 #if 1 4382 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); 4383 for (p = 0; p < supportSize; ++p) { 4384 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); 4385 } 4386 #endif 4387 } 4388 } 4389 /* Interior faces have 4 edges and 2 cells */ 4390 for (c = cStart; c < cEnd; ++c) { 4391 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 4392 const PetscInt *cone, *ornt; 4393 PetscInt coneNew[4], orntNew[4]; 4394 PetscInt supportNew[2]; 4395 4396 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4397 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4398 /* Face {a, g, m, h} */ 4399 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 4400 orntNew[0] = 0; 4401 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4402 orntNew[1] = 0; 4403 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4404 orntNew[2] = -2; 4405 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 4406 orntNew[3] = -2; 4407 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4408 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4409 #if 1 4410 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4411 for (p = 0; p < 4; ++p) { 4412 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); 4413 } 4414 #endif 4415 supportNew[0] = (c - cStart)*4 + 0; 4416 supportNew[1] = (c - cStart)*4 + 1; 4417 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4418 #if 1 4419 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4420 for (p = 0; p < 2; ++p) { 4421 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); 4422 } 4423 #endif 4424 ++newp; 4425 /* Face {g, b, l , m} */ 4426 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 4427 orntNew[0] = -2; 4428 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 4429 orntNew[1] = 0; 4430 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4431 orntNew[2] = 0; 4432 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4433 orntNew[3] = -2; 4434 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4435 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4436 #if 1 4437 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4438 for (p = 0; p < 4; ++p) { 4439 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); 4440 } 4441 #endif 4442 supportNew[0] = (c - cStart)*4 + 1; 4443 supportNew[1] = (c - cStart)*4 + 2; 4444 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4445 #if 1 4446 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4447 for (p = 0; p < 2; ++p) { 4448 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); 4449 } 4450 #endif 4451 ++newp; 4452 /* Face {c, g, m, i} */ 4453 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 4454 orntNew[0] = 0; 4455 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4456 orntNew[1] = 0; 4457 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4458 orntNew[2] = -2; 4459 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 4460 orntNew[3] = -2; 4461 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4462 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4463 #if 1 4464 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4465 for (p = 0; p < 4; ++p) { 4466 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); 4467 } 4468 #endif 4469 supportNew[0] = (c - cStart)*4 + 0; 4470 supportNew[1] = (c - cStart)*4 + 2; 4471 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4472 #if 1 4473 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4474 for (p = 0; p < 2; ++p) { 4475 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); 4476 } 4477 #endif 4478 ++newp; 4479 /* Face {d, h, m, i} */ 4480 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 4481 orntNew[0] = 0; 4482 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4483 orntNew[1] = 0; 4484 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4485 orntNew[2] = -2; 4486 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 4487 orntNew[3] = -2; 4488 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4489 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4490 #if 1 4491 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4492 for (p = 0; p < 4; ++p) { 4493 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); 4494 } 4495 #endif 4496 supportNew[0] = (c - cStart)*4 + 0; 4497 supportNew[1] = (c - cStart)*4 + 3; 4498 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4499 #if 1 4500 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4501 for (p = 0; p < 2; ++p) { 4502 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); 4503 } 4504 #endif 4505 ++newp; 4506 /* Face {h, m, l, e} */ 4507 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4508 orntNew[0] = 0; 4509 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4510 orntNew[1] = -2; 4511 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 4512 orntNew[2] = -2; 4513 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 4514 orntNew[3] = 0; 4515 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4516 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4517 #if 1 4518 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4519 for (p = 0; p < 4; ++p) { 4520 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); 4521 } 4522 #endif 4523 supportNew[0] = (c - cStart)*4 + 1; 4524 supportNew[1] = (c - cStart)*4 + 3; 4525 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4526 #if 1 4527 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4528 for (p = 0; p < 2; ++p) { 4529 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); 4530 } 4531 #endif 4532 ++newp; 4533 /* Face {i, m, l, f} */ 4534 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4535 orntNew[0] = 0; 4536 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4537 orntNew[1] = -2; 4538 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 4539 orntNew[2] = -2; 4540 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 4541 orntNew[3] = 0; 4542 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4543 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4544 #if 1 4545 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4546 for (p = 0; p < 4; ++p) { 4547 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); 4548 } 4549 #endif 4550 supportNew[0] = (c - cStart)*4 + 2; 4551 supportNew[1] = (c - cStart)*4 + 3; 4552 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4553 #if 1 4554 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4555 for (p = 0; p < 2; ++p) { 4556 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); 4557 } 4558 #endif 4559 ++newp; 4560 } 4561 /* Split Edges have 2 vertices and the same faces as the parent */ 4562 for (e = eStart; e < eEnd; ++e) { 4563 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4564 4565 for (r = 0; r < 2; ++r) { 4566 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4567 const PetscInt *cone, *ornt, *support; 4568 PetscInt coneNew[2], coneSize, c, supportSize, s; 4569 4570 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4571 coneNew[0] = vStartNew + (cone[0] - vStart); 4572 coneNew[1] = vStartNew + (cone[1] - vStart); 4573 coneNew[(r+1)%2] = newv; 4574 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4575 #if 1 4576 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4577 for (p = 0; p < 2; ++p) { 4578 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); 4579 } 4580 #endif 4581 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4582 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4583 for (s = 0; s < supportSize; ++s) { 4584 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4585 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4586 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4587 for (c = 0; c < coneSize; ++c) { 4588 if (cone[c] == e) break; 4589 } 4590 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4591 } 4592 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4593 #if 1 4594 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4595 for (p = 0; p < supportSize; ++p) { 4596 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); 4597 } 4598 #endif 4599 } 4600 } 4601 /* Face edges have 2 vertices and 2 + cell faces supports */ 4602 for (f = fStart; f < fEnd; ++f) { 4603 const PetscInt *cone, *ornt, *support; 4604 PetscInt coneSize, supportSize, s; 4605 4606 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4607 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4608 for (r = 0; r < 3; ++r) { 4609 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 4610 PetscInt coneNew[2]; 4611 PetscInt fint[4][3] = { {0, 1, 2}, 4612 {3, 4, 0}, 4613 {2, 5, 3}, 4614 {1, 4, 5} }; 4615 4616 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4617 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4618 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 4619 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4620 #if 1 4621 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4622 for (p = 0; p < 2; ++p) { 4623 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); 4624 } 4625 #endif 4626 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 4627 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 4628 for (s = 0; s < supportSize; ++s) { 4629 PetscInt er; 4630 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4631 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4632 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4633 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4634 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 4635 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 4636 } 4637 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4638 #if 1 4639 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4640 for (p = 0; p < supportSize + 2; ++p) { 4641 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); 4642 } 4643 #endif 4644 } 4645 } 4646 /* Interior cell edges have 2 vertices and 3 faces */ 4647 for (c = cStart; c < cEnd; ++c) { 4648 const PetscInt *cone; 4649 PetscInt fint[4][3] = { {0,1,2}, 4650 {0,3,4}, 4651 {2,3,5}, 4652 {1,4,5} } ; 4653 4654 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4655 for (r = 0; r < 4; r++) { 4656 PetscInt coneNew[2], supportNew[3]; 4657 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 4658 4659 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4660 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 4661 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4662 #if 1 4663 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4664 for (p = 0; p < 2; ++p) { 4665 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); 4666 } 4667 #endif 4668 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 4669 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 4670 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 4671 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4672 #if 1 4673 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4674 for (p = 0; p < 3; ++p) { 4675 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); 4676 } 4677 #endif 4678 } 4679 } 4680 /* Old vertices have identical supports */ 4681 for (v = vStart; v < vEnd; ++v) { 4682 const PetscInt newp = vStartNew + (v - vStart); 4683 const PetscInt *support, *cone; 4684 PetscInt size, s; 4685 4686 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4687 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4688 for (s = 0; s < size; ++s) { 4689 PetscInt r = 0; 4690 4691 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4692 if (cone[1] == v) r = 1; 4693 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4694 } 4695 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4696 #if 1 4697 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4698 for (p = 0; p < size; ++p) { 4699 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); 4700 } 4701 #endif 4702 } 4703 /* Edge vertices have 2 + faces supports */ 4704 for (e = eStart; e < eEnd; ++e) { 4705 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4706 const PetscInt *cone, *support; 4707 PetscInt size, s; 4708 4709 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4710 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4711 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4712 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4713 for (s = 0; s < size; ++s) { 4714 PetscInt r = 0, coneSize; 4715 4716 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4717 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4718 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4719 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 4720 } 4721 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4722 #if 1 4723 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4724 for (p = 0; p < 2+size; ++p) { 4725 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); 4726 } 4727 #endif 4728 } 4729 /* Face vertices have 3 + cells supports */ 4730 for (f = fStart; f < fEnd; ++f) { 4731 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4732 const PetscInt *cone, *support; 4733 PetscInt size, s; 4734 4735 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4736 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4737 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4738 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4739 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4740 for (s = 0; s < size; ++s) { 4741 PetscInt r = 0, coneSize; 4742 4743 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4744 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4745 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 4746 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 4747 } 4748 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4749 #if 1 4750 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4751 for (p = 0; p < 3+size; ++p) { 4752 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); 4753 } 4754 #endif 4755 } 4756 /* Interior cell vertices have 4 supports */ 4757 for (c = cStart; c < cEnd; ++c) { 4758 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 4759 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4760 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4761 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4762 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4763 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4764 #if 1 4765 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4766 for (p = 0; p < 4; ++p) { 4767 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); 4768 } 4769 #endif 4770 } 4771 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4772 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4773 break; 4774 case REFINER_HEX_3D: 4775 /* 4776 Bottom (viewed from top) Top 4777 1---------2---------2 7---------2---------6 4778 | | | | | | 4779 | B 2 C | | H 2 G | 4780 | | | | | | 4781 3----3----0----1----1 3----3----0----1----1 4782 | | | | | | 4783 | A 0 D | | E 0 F | 4784 | | | | | | 4785 0---------0---------3 4---------0---------5 4786 */ 4787 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4788 for (c = cStart; c < cEnd; ++c) { 4789 const PetscInt newp = (c - cStart)*8; 4790 const PetscInt *cone, *ornt; 4791 PetscInt coneNew[6], orntNew[6]; 4792 4793 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4794 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4795 /* A hex */ 4796 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4797 orntNew[0] = ornt[0]; 4798 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4799 orntNew[1] = 0; 4800 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4801 orntNew[2] = ornt[2]; 4802 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4803 orntNew[3] = 0; 4804 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4805 orntNew[4] = 0; 4806 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4807 orntNew[5] = ornt[5]; 4808 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4809 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4810 #if 1 4811 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); 4812 for (p = 0; p < 6; ++p) { 4813 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); 4814 } 4815 #endif 4816 /* B hex */ 4817 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4818 orntNew[0] = ornt[0]; 4819 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4820 orntNew[1] = 0; 4821 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4822 orntNew[2] = -1; 4823 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4824 orntNew[3] = ornt[3]; 4825 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4826 orntNew[4] = 0; 4827 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4828 orntNew[5] = ornt[5]; 4829 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4830 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4831 #if 1 4832 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); 4833 for (p = 0; p < 6; ++p) { 4834 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); 4835 } 4836 #endif 4837 /* C hex */ 4838 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4839 orntNew[0] = ornt[0]; 4840 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4841 orntNew[1] = 0; 4842 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4843 orntNew[2] = -1; 4844 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4845 orntNew[3] = ornt[3]; 4846 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4847 orntNew[4] = ornt[4]; 4848 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4849 orntNew[5] = -4; 4850 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4851 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4852 #if 1 4853 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); 4854 for (p = 0; p < 6; ++p) { 4855 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); 4856 } 4857 #endif 4858 /* D hex */ 4859 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4860 orntNew[0] = ornt[0]; 4861 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4862 orntNew[1] = 0; 4863 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4864 orntNew[2] = ornt[2]; 4865 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4866 orntNew[3] = 0; 4867 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4868 orntNew[4] = ornt[4]; 4869 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4870 orntNew[5] = -4; 4871 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4872 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4873 #if 1 4874 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); 4875 for (p = 0; p < 6; ++p) { 4876 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); 4877 } 4878 #endif 4879 /* E hex */ 4880 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4881 orntNew[0] = -4; 4882 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4883 orntNew[1] = ornt[1]; 4884 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4885 orntNew[2] = ornt[2]; 4886 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4887 orntNew[3] = 0; 4888 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4889 orntNew[4] = -1; 4890 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4891 orntNew[5] = ornt[5]; 4892 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4893 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4894 #if 1 4895 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); 4896 for (p = 0; p < 6; ++p) { 4897 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); 4898 } 4899 #endif 4900 /* F hex */ 4901 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4902 orntNew[0] = -4; 4903 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4904 orntNew[1] = ornt[1]; 4905 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4906 orntNew[2] = ornt[2]; 4907 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4908 orntNew[3] = -1; 4909 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4910 orntNew[4] = ornt[4]; 4911 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4912 orntNew[5] = 1; 4913 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4914 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4915 #if 1 4916 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); 4917 for (p = 0; p < 6; ++p) { 4918 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); 4919 } 4920 #endif 4921 /* G hex */ 4922 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4923 orntNew[0] = -4; 4924 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4925 orntNew[1] = ornt[1]; 4926 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4927 orntNew[2] = 0; 4928 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4929 orntNew[3] = ornt[3]; 4930 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4931 orntNew[4] = ornt[4]; 4932 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4933 orntNew[5] = -3; 4934 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4935 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4936 #if 1 4937 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); 4938 for (p = 0; p < 6; ++p) { 4939 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); 4940 } 4941 #endif 4942 /* H hex */ 4943 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4944 orntNew[0] = -4; 4945 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4946 orntNew[1] = ornt[1]; 4947 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4948 orntNew[2] = -1; 4949 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4950 orntNew[3] = ornt[3]; 4951 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4952 orntNew[4] = 3; 4953 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4954 orntNew[5] = ornt[5]; 4955 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4956 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4957 #if 1 4958 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); 4959 for (p = 0; p < 6; ++p) { 4960 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); 4961 } 4962 #endif 4963 } 4964 /* Split faces have 4 edges and the same cells as the parent */ 4965 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4966 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4967 for (f = fStart; f < fEnd; ++f) { 4968 for (r = 0; r < 4; ++r) { 4969 /* TODO: This can come from GetFaces_Internal() */ 4970 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}; 4971 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4972 const PetscInt *cone, *ornt, *support; 4973 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4974 4975 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4976 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4977 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4978 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4979 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4980 orntNew[(r+0)%4] = ornt[r]; 4981 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4982 orntNew[(r+1)%4] = 0; 4983 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4984 orntNew[(r+2)%4] = -2; 4985 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4986 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4987 #if 1 4988 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4989 for (p = 0; p < 4; ++p) { 4990 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); 4991 } 4992 #endif 4993 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4994 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4995 for (s = 0; s < supportSize; ++s) { 4996 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4997 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4998 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4999 for (c = 0; c < coneSize; ++c) { 5000 if (cone[c] == f) break; 5001 } 5002 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 5003 } 5004 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5005 #if 1 5006 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5007 for (p = 0; p < supportSize; ++p) { 5008 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); 5009 } 5010 #endif 5011 } 5012 } 5013 /* Interior faces have 4 edges and 2 cells */ 5014 for (c = cStart; c < cEnd; ++c) { 5015 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}; 5016 const PetscInt *cone, *ornt; 5017 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 5018 5019 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5020 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5021 /* A-D face */ 5022 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 5023 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 5024 orntNew[0] = 0; 5025 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5026 orntNew[1] = 0; 5027 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5028 orntNew[2] = -2; 5029 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 5030 orntNew[3] = -2; 5031 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5032 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5033 #if 1 5034 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5035 for (p = 0; p < 4; ++p) { 5036 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); 5037 } 5038 #endif 5039 /* C-D face */ 5040 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 5041 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 5042 orntNew[0] = 0; 5043 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5044 orntNew[1] = 0; 5045 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5046 orntNew[2] = -2; 5047 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 5048 orntNew[3] = -2; 5049 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5050 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5051 #if 1 5052 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5053 for (p = 0; p < 4; ++p) { 5054 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); 5055 } 5056 #endif 5057 /* B-C face */ 5058 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 5059 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 5060 orntNew[0] = -2; 5061 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 5062 orntNew[1] = 0; 5063 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5064 orntNew[2] = 0; 5065 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5066 orntNew[3] = -2; 5067 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5068 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5069 #if 1 5070 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5071 for (p = 0; p < 4; ++p) { 5072 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); 5073 } 5074 #endif 5075 /* A-B face */ 5076 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 5077 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 5078 orntNew[0] = -2; 5079 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 5080 orntNew[1] = 0; 5081 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5082 orntNew[2] = 0; 5083 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5084 orntNew[3] = -2; 5085 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5086 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5087 #if 1 5088 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5089 for (p = 0; p < 4; ++p) { 5090 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); 5091 } 5092 #endif 5093 /* E-F face */ 5094 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 5095 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5096 orntNew[0] = -2; 5097 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 5098 orntNew[1] = -2; 5099 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 5100 orntNew[2] = 0; 5101 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5102 orntNew[3] = 0; 5103 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5104 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5105 #if 1 5106 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5107 for (p = 0; p < 4; ++p) { 5108 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); 5109 } 5110 #endif 5111 /* F-G face */ 5112 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 5113 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5114 orntNew[0] = -2; 5115 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 5116 orntNew[1] = -2; 5117 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 5118 orntNew[2] = 0; 5119 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5120 orntNew[3] = 0; 5121 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5122 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5123 #if 1 5124 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5125 for (p = 0; p < 4; ++p) { 5126 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); 5127 } 5128 #endif 5129 /* G-H face */ 5130 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 5131 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 5132 orntNew[0] = -2; 5133 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 5134 orntNew[1] = 0; 5135 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5136 orntNew[2] = 0; 5137 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5138 orntNew[3] = -2; 5139 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5140 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5141 #if 1 5142 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5143 for (p = 0; p < 4; ++p) { 5144 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); 5145 } 5146 #endif 5147 /* E-H face */ 5148 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 5149 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5150 orntNew[0] = -2; 5151 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 5152 orntNew[1] = -2; 5153 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 5154 orntNew[2] = 0; 5155 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5156 orntNew[3] = 0; 5157 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5158 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5159 #if 1 5160 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5161 for (p = 0; p < 4; ++p) { 5162 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); 5163 } 5164 #endif 5165 /* A-E face */ 5166 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 5167 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 5168 orntNew[0] = 0; 5169 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5170 orntNew[1] = 0; 5171 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5172 orntNew[2] = -2; 5173 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 5174 orntNew[3] = -2; 5175 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5176 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5177 #if 1 5178 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5179 for (p = 0; p < 4; ++p) { 5180 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); 5181 } 5182 #endif 5183 /* D-F face */ 5184 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 5185 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 5186 orntNew[0] = -2; 5187 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 5188 orntNew[1] = 0; 5189 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5190 orntNew[2] = 0; 5191 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5192 orntNew[3] = -2; 5193 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5194 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5195 #if 1 5196 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5197 for (p = 0; p < 4; ++p) { 5198 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); 5199 } 5200 #endif 5201 /* C-G face */ 5202 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 5203 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5204 orntNew[0] = -2; 5205 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 5206 orntNew[1] = -2; 5207 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 5208 orntNew[2] = 0; 5209 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5210 orntNew[3] = 0; 5211 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5212 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5213 #if 1 5214 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5215 for (p = 0; p < 4; ++p) { 5216 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); 5217 } 5218 #endif 5219 /* B-H face */ 5220 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 5221 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5222 orntNew[0] = 0; 5223 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5224 orntNew[1] = -2; 5225 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 5226 orntNew[2] = -2; 5227 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 5228 orntNew[3] = 0; 5229 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5230 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5231 #if 1 5232 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5233 for (p = 0; p < 4; ++p) { 5234 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); 5235 } 5236 #endif 5237 for (r = 0; r < 12; ++r) { 5238 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 5239 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 5240 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 5241 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5242 #if 1 5243 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5244 for (p = 0; p < 2; ++p) { 5245 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); 5246 } 5247 #endif 5248 } 5249 } 5250 /* Split edges have 2 vertices and the same faces as the parent */ 5251 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5252 for (e = eStart; e < eEnd; ++e) { 5253 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5254 5255 for (r = 0; r < 2; ++r) { 5256 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5257 const PetscInt *cone, *ornt, *support; 5258 PetscInt coneNew[2], coneSize, c, supportSize, s; 5259 5260 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5261 coneNew[0] = vStartNew + (cone[0] - vStart); 5262 coneNew[1] = vStartNew + (cone[1] - vStart); 5263 coneNew[(r+1)%2] = newv; 5264 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5265 #if 1 5266 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5267 for (p = 0; p < 2; ++p) { 5268 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); 5269 } 5270 #endif 5271 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5272 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5273 for (s = 0; s < supportSize; ++s) { 5274 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5275 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5276 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5277 for (c = 0; c < coneSize; ++c) { 5278 if (cone[c] == e) break; 5279 } 5280 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 5281 } 5282 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5283 #if 1 5284 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5285 for (p = 0; p < supportSize; ++p) { 5286 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); 5287 } 5288 #endif 5289 } 5290 } 5291 /* Face edges have 2 vertices and 2+cells faces */ 5292 for (f = fStart; f < fEnd; ++f) { 5293 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}; 5294 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5295 const PetscInt *cone, *coneCell, *orntCell, *support; 5296 PetscInt coneNew[2], coneSize, c, supportSize, s; 5297 5298 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5299 for (r = 0; r < 4; ++r) { 5300 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5301 5302 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5303 coneNew[1] = newv; 5304 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5305 #if 1 5306 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5307 for (p = 0; p < 2; ++p) { 5308 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); 5309 } 5310 #endif 5311 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5312 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5313 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5314 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5315 for (s = 0; s < supportSize; ++s) { 5316 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5317 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5318 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5319 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5320 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5321 } 5322 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5323 #if 1 5324 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5325 for (p = 0; p < 2+supportSize; ++p) { 5326 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); 5327 } 5328 #endif 5329 } 5330 } 5331 /* Cell edges have 2 vertices and 4 faces */ 5332 for (c = cStart; c < cEnd; ++c) { 5333 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}; 5334 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 5335 const PetscInt *cone; 5336 PetscInt coneNew[2], supportNew[4]; 5337 5338 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5339 for (r = 0; r < 6; ++r) { 5340 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 5341 5342 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5343 coneNew[1] = newv; 5344 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5345 #if 1 5346 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5347 for (p = 0; p < 2; ++p) { 5348 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); 5349 } 5350 #endif 5351 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5352 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5353 #if 1 5354 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5355 for (p = 0; p < 4; ++p) { 5356 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); 5357 } 5358 #endif 5359 } 5360 } 5361 /* Old vertices have identical supports */ 5362 for (v = vStart; v < vEnd; ++v) { 5363 const PetscInt newp = vStartNew + (v - vStart); 5364 const PetscInt *support, *cone; 5365 PetscInt size, s; 5366 5367 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5368 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5369 for (s = 0; s < size; ++s) { 5370 PetscInt r = 0; 5371 5372 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5373 if (cone[1] == v) r = 1; 5374 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5375 } 5376 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5377 #if 1 5378 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5379 for (p = 0; p < size; ++p) { 5380 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); 5381 } 5382 #endif 5383 } 5384 /* Edge vertices have 2 + faces supports */ 5385 for (e = eStart; e < eEnd; ++e) { 5386 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5387 const PetscInt *cone, *support; 5388 PetscInt size, s; 5389 5390 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5391 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5392 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5393 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5394 for (s = 0; s < size; ++s) { 5395 PetscInt r; 5396 5397 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5398 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5399 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 5400 } 5401 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5402 #if 1 5403 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5404 for (p = 0; p < 2+size; ++p) { 5405 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); 5406 } 5407 #endif 5408 } 5409 /* Face vertices have 4 + cells supports */ 5410 for (f = fStart; f < fEnd; ++f) { 5411 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5412 const PetscInt *cone, *support; 5413 PetscInt size, s; 5414 5415 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5416 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5417 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5418 for (s = 0; s < size; ++s) { 5419 PetscInt r; 5420 5421 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5422 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5423 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 5424 } 5425 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5426 #if 1 5427 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5428 for (p = 0; p < 4+size; ++p) { 5429 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); 5430 } 5431 #endif 5432 } 5433 /* Cell vertices have 6 supports */ 5434 for (c = cStart; c < cEnd; ++c) { 5435 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 5436 PetscInt supportNew[6]; 5437 5438 for (r = 0; r < 6; ++r) { 5439 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 5440 } 5441 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5442 } 5443 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5444 break; 5445 case REFINER_HYBRID_HEX_3D: 5446 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 5447 /* 5448 Bottom (viewed from top) Top 5449 1---------2---------2 7---------2---------6 5450 | | | | | | 5451 | B 2 C | | H 2 G | 5452 | | | | | | 5453 3----3----0----1----1 3----3----0----1----1 5454 | | | | | | 5455 | A 0 D | | E 0 F | 5456 | | | | | | 5457 0---------0---------3 4---------0---------5 5458 */ 5459 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 5460 for (c = cStart; c < cMax; ++c) { 5461 const PetscInt newp = (c - cStart)*8; 5462 const PetscInt *cone, *ornt; 5463 PetscInt coneNew[6], orntNew[6]; 5464 5465 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5466 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5467 /* A hex */ 5468 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 5469 orntNew[0] = ornt[0]; 5470 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 5471 orntNew[1] = 0; 5472 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 5473 orntNew[2] = ornt[2]; 5474 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 5475 orntNew[3] = 0; 5476 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 5477 orntNew[4] = 0; 5478 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 5479 orntNew[5] = ornt[5]; 5480 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5481 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5482 #if 1 5483 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); 5484 for (p = 0; p < 6; ++p) { 5485 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); 5486 } 5487 #endif 5488 /* B hex */ 5489 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 5490 orntNew[0] = ornt[0]; 5491 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5492 orntNew[1] = 0; 5493 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 5494 orntNew[2] = -1; 5495 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 5496 orntNew[3] = ornt[3]; 5497 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 5498 orntNew[4] = 0; 5499 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 5500 orntNew[5] = ornt[5]; 5501 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5502 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5503 #if 1 5504 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); 5505 for (p = 0; p < 6; ++p) { 5506 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); 5507 } 5508 #endif 5509 /* C hex */ 5510 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 5511 orntNew[0] = ornt[0]; 5512 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 5513 orntNew[1] = 0; 5514 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 5515 orntNew[2] = -1; 5516 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 5517 orntNew[3] = ornt[3]; 5518 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 5519 orntNew[4] = ornt[4]; 5520 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 5521 orntNew[5] = -4; 5522 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5523 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5524 #if 1 5525 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); 5526 for (p = 0; p < 6; ++p) { 5527 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); 5528 } 5529 #endif 5530 /* D hex */ 5531 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 5532 orntNew[0] = ornt[0]; 5533 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 5534 orntNew[1] = 0; 5535 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 5536 orntNew[2] = ornt[2]; 5537 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 5538 orntNew[3] = 0; 5539 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 5540 orntNew[4] = ornt[4]; 5541 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 5542 orntNew[5] = -4; 5543 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5544 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5545 #if 1 5546 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); 5547 for (p = 0; p < 6; ++p) { 5548 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); 5549 } 5550 #endif 5551 /* E hex */ 5552 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 5553 orntNew[0] = -4; 5554 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 5555 orntNew[1] = ornt[1]; 5556 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 5557 orntNew[2] = ornt[2]; 5558 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5559 orntNew[3] = 0; 5560 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 5561 orntNew[4] = -1; 5562 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 5563 orntNew[5] = ornt[5]; 5564 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 5565 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 5566 #if 1 5567 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); 5568 for (p = 0; p < 6; ++p) { 5569 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); 5570 } 5571 #endif 5572 /* F hex */ 5573 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 5574 orntNew[0] = -4; 5575 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 5576 orntNew[1] = ornt[1]; 5577 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 5578 orntNew[2] = ornt[2]; 5579 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5580 orntNew[3] = -1; 5581 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 5582 orntNew[4] = ornt[4]; 5583 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 5584 orntNew[5] = 1; 5585 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 5586 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 5587 #if 1 5588 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); 5589 for (p = 0; p < 6; ++p) { 5590 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); 5591 } 5592 #endif 5593 /* G hex */ 5594 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 5595 orntNew[0] = -4; 5596 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 5597 orntNew[1] = ornt[1]; 5598 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5599 orntNew[2] = 0; 5600 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 5601 orntNew[3] = ornt[3]; 5602 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 5603 orntNew[4] = ornt[4]; 5604 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5605 orntNew[5] = -3; 5606 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 5607 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 5608 #if 1 5609 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); 5610 for (p = 0; p < 6; ++p) { 5611 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); 5612 } 5613 #endif 5614 /* H hex */ 5615 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5616 orntNew[0] = -4; 5617 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 5618 orntNew[1] = ornt[1]; 5619 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5620 orntNew[2] = -1; 5621 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 5622 orntNew[3] = ornt[3]; 5623 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5624 orntNew[4] = 3; 5625 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 5626 orntNew[5] = ornt[5]; 5627 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 5628 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 5629 #if 1 5630 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); 5631 for (p = 0; p < 6; ++p) { 5632 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); 5633 } 5634 #endif 5635 } 5636 /* Hybrid cells have 6 faces: Front, Back, Sides */ 5637 /* 5638 3---------2---------2 5639 | | | 5640 | D 2 C | 5641 | | | 5642 3----3----0----1----1 5643 | | | 5644 | A 0 B | 5645 | | | 5646 0---------0---------1 5647 */ 5648 for (c = cMax; c < cEnd; ++c) { 5649 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 5650 const PetscInt *cone, *ornt, *fornt; 5651 PetscInt coneNew[6], orntNew[6], o, of, i; 5652 5653 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5654 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5655 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 5656 o = ornt[0] < 0 ? -1 : 1; 5657 for (r = 0; r < 4; ++r) { 5658 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 5659 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 5660 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 5661 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]); 5662 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 5663 orntNew[0] = ornt[0]; 5664 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 5665 orntNew[1] = ornt[0]; 5666 of = fornt[edgeA] < 0 ? -1 : 1; 5667 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 5668 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 5669 orntNew[i] = ornt[edgeA]; 5670 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 5671 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 5672 orntNew[i] = 0; 5673 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 5674 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 5675 orntNew[i] = -2; 5676 of = fornt[edgeB] < 0 ? -1 : 1; 5677 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 5678 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 5679 orntNew[i] = ornt[edgeB]; 5680 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 5681 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 5682 #if 1 5683 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); 5684 for (p = 0; p < 2; ++p) { 5685 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); 5686 } 5687 for (p = 2; p < 6; ++p) { 5688 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); 5689 } 5690 #endif 5691 } 5692 } 5693 /* Interior split faces have 4 edges and the same cells as the parent */ 5694 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5695 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5696 for (f = fStart; f < fMax; ++f) { 5697 for (r = 0; r < 4; ++r) { 5698 /* TODO: This can come from GetFaces_Internal() */ 5699 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}; 5700 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 5701 const PetscInt *cone, *ornt, *support; 5702 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 5703 5704 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5705 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5706 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 5707 orntNew[(r+3)%4] = ornt[(r+3)%4]; 5708 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 5709 orntNew[(r+0)%4] = ornt[r]; 5710 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5711 orntNew[(r+1)%4] = 0; 5712 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 5713 orntNew[(r+2)%4] = -2; 5714 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5715 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5716 #if 1 5717 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5718 for (p = 0; p < 4; ++p) { 5719 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); 5720 } 5721 #endif 5722 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5723 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5724 for (s = 0; s < supportSize; ++s) { 5725 PetscInt subf; 5726 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5727 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5728 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5729 for (c = 0; c < coneSize; ++c) { 5730 if (cone[c] == f) break; 5731 } 5732 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 5733 if (support[s] < cMax) { 5734 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 5735 } else { 5736 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 5737 } 5738 } 5739 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5740 #if 1 5741 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5742 for (p = 0; p < supportSize; ++p) { 5743 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); 5744 } 5745 #endif 5746 } 5747 } 5748 /* Interior cell faces have 4 edges and 2 cells */ 5749 for (c = cStart; c < cMax; ++c) { 5750 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}; 5751 const PetscInt *cone, *ornt; 5752 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 5753 5754 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5755 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5756 /* A-D face */ 5757 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 5758 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 5759 orntNew[0] = 0; 5760 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5761 orntNew[1] = 0; 5762 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5763 orntNew[2] = -2; 5764 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 5765 orntNew[3] = -2; 5766 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5767 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5768 #if 1 5769 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5770 for (p = 0; p < 4; ++p) { 5771 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); 5772 } 5773 #endif 5774 /* C-D face */ 5775 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 5776 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 5777 orntNew[0] = 0; 5778 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5779 orntNew[1] = 0; 5780 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5781 orntNew[2] = -2; 5782 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 5783 orntNew[3] = -2; 5784 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5785 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5786 #if 1 5787 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5788 for (p = 0; p < 4; ++p) { 5789 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); 5790 } 5791 #endif 5792 /* B-C face */ 5793 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 5794 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 5795 orntNew[0] = -2; 5796 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 5797 orntNew[1] = 0; 5798 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5799 orntNew[2] = 0; 5800 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5801 orntNew[3] = -2; 5802 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5803 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5804 #if 1 5805 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5806 for (p = 0; p < 4; ++p) { 5807 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); 5808 } 5809 #endif 5810 /* A-B face */ 5811 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 5812 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 5813 orntNew[0] = -2; 5814 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 5815 orntNew[1] = 0; 5816 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5817 orntNew[2] = 0; 5818 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5819 orntNew[3] = -2; 5820 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5821 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5822 #if 1 5823 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5824 for (p = 0; p < 4; ++p) { 5825 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); 5826 } 5827 #endif 5828 /* E-F face */ 5829 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 5830 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5831 orntNew[0] = -2; 5832 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 5833 orntNew[1] = -2; 5834 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 5835 orntNew[2] = 0; 5836 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5837 orntNew[3] = 0; 5838 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5839 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5840 #if 1 5841 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5842 for (p = 0; p < 4; ++p) { 5843 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); 5844 } 5845 #endif 5846 /* F-G face */ 5847 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 5848 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5849 orntNew[0] = -2; 5850 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 5851 orntNew[1] = -2; 5852 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 5853 orntNew[2] = 0; 5854 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5855 orntNew[3] = 0; 5856 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5857 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5858 #if 1 5859 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5860 for (p = 0; p < 4; ++p) { 5861 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); 5862 } 5863 #endif 5864 /* G-H face */ 5865 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 5866 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 5867 orntNew[0] = -2; 5868 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 5869 orntNew[1] = 0; 5870 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5871 orntNew[2] = 0; 5872 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5873 orntNew[3] = -2; 5874 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5875 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5876 #if 1 5877 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5878 for (p = 0; p < 4; ++p) { 5879 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); 5880 } 5881 #endif 5882 /* E-H face */ 5883 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 5884 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5885 orntNew[0] = -2; 5886 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 5887 orntNew[1] = -2; 5888 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 5889 orntNew[2] = 0; 5890 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5891 orntNew[3] = 0; 5892 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5893 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5894 #if 1 5895 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5896 for (p = 0; p < 4; ++p) { 5897 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); 5898 } 5899 #endif 5900 /* A-E face */ 5901 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 5902 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 5903 orntNew[0] = 0; 5904 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5905 orntNew[1] = 0; 5906 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5907 orntNew[2] = -2; 5908 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 5909 orntNew[3] = -2; 5910 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5911 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5912 #if 1 5913 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5914 for (p = 0; p < 4; ++p) { 5915 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); 5916 } 5917 #endif 5918 /* D-F face */ 5919 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 5920 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 5921 orntNew[0] = -2; 5922 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 5923 orntNew[1] = 0; 5924 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5925 orntNew[2] = 0; 5926 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5927 orntNew[3] = -2; 5928 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5929 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5930 #if 1 5931 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5932 for (p = 0; p < 4; ++p) { 5933 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); 5934 } 5935 #endif 5936 /* C-G face */ 5937 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 5938 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5939 orntNew[0] = -2; 5940 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 5941 orntNew[1] = -2; 5942 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 5943 orntNew[2] = 0; 5944 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5945 orntNew[3] = 0; 5946 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5947 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5948 #if 1 5949 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5950 for (p = 0; p < 4; ++p) { 5951 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); 5952 } 5953 #endif 5954 /* B-H face */ 5955 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 5956 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5957 orntNew[0] = 0; 5958 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5959 orntNew[1] = -2; 5960 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 5961 orntNew[2] = -2; 5962 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 5963 orntNew[3] = 0; 5964 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5965 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5966 #if 1 5967 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5968 for (p = 0; p < 4; ++p) { 5969 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); 5970 } 5971 #endif 5972 for (r = 0; r < 12; ++r) { 5973 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 5974 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 5975 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 5976 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5977 #if 1 5978 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5979 for (p = 0; p < 2; ++p) { 5980 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); 5981 } 5982 #endif 5983 } 5984 } 5985 /* Hybrid split faces have 4 edges and same cells */ 5986 for (f = fMax; f < fEnd; ++f) { 5987 const PetscInt *cone, *ornt, *support; 5988 PetscInt coneNew[4], orntNew[4]; 5989 PetscInt supportNew[2], size, s, c; 5990 5991 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5992 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5993 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5994 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5995 for (r = 0; r < 2; ++r) { 5996 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 5997 5998 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 5999 orntNew[0] = ornt[0]; 6000 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 6001 orntNew[1] = ornt[1]; 6002 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 6003 orntNew[2+r] = 0; 6004 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 6005 orntNew[3-r] = 0; 6006 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6007 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6008 #if 1 6009 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 6010 for (p = 0; p < 2; ++p) { 6011 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); 6012 } 6013 for (p = 2; p < 4; ++p) { 6014 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); 6015 } 6016 #endif 6017 for (s = 0; s < size; ++s) { 6018 const PetscInt *coneCell, *orntCell, *fornt; 6019 PetscInt o, of; 6020 6021 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6022 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6023 o = orntCell[0] < 0 ? -1 : 1; 6024 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 6025 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 6026 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 6027 of = fornt[c-2] < 0 ? -1 : 1; 6028 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 6029 } 6030 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6031 #if 1 6032 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 6033 for (p = 0; p < size; ++p) { 6034 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); 6035 } 6036 #endif 6037 } 6038 } 6039 /* Hybrid cell faces have 4 edges and 2 cells */ 6040 for (c = cMax; c < cEnd; ++c) { 6041 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 6042 const PetscInt *cone, *ornt; 6043 PetscInt coneNew[4], orntNew[4]; 6044 PetscInt supportNew[2]; 6045 6046 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6047 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6048 for (r = 0; r < 4; ++r) { 6049 #if 0 6050 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 6051 orntNew[0] = 0; 6052 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 6053 orntNew[1] = 0; 6054 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 6055 orntNew[2] = 0; 6056 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6057 orntNew[3] = 0; 6058 #else 6059 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 6060 orntNew[0] = 0; 6061 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 6062 orntNew[1] = 0; 6063 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 6064 orntNew[2] = 0; 6065 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6066 orntNew[3] = 0; 6067 #endif 6068 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 6069 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 6070 #if 1 6071 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); 6072 for (p = 0; p < 2; ++p) { 6073 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); 6074 } 6075 for (p = 2; p < 4; ++p) { 6076 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); 6077 } 6078 #endif 6079 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 6080 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 6081 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 6082 #if 1 6083 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); 6084 for (p = 0; p < 2; ++p) { 6085 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); 6086 } 6087 #endif 6088 } 6089 } 6090 /* Interior split edges have 2 vertices and the same faces as the parent */ 6091 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6092 for (e = eStart; e < eMax; ++e) { 6093 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6094 6095 for (r = 0; r < 2; ++r) { 6096 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6097 const PetscInt *cone, *ornt, *support; 6098 PetscInt coneNew[2], coneSize, c, supportSize, s; 6099 6100 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6101 coneNew[0] = vStartNew + (cone[0] - vStart); 6102 coneNew[1] = vStartNew + (cone[1] - vStart); 6103 coneNew[(r+1)%2] = newv; 6104 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6105 #if 1 6106 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6107 for (p = 0; p < 2; ++p) { 6108 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); 6109 } 6110 #endif 6111 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6112 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6113 for (s = 0; s < supportSize; ++s) { 6114 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6115 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6116 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6117 for (c = 0; c < coneSize; ++c) { 6118 if (cone[c] == e) break; 6119 } 6120 if (support[s] < fMax) { 6121 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 6122 } else { 6123 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6124 } 6125 } 6126 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6127 #if 1 6128 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6129 for (p = 0; p < supportSize; ++p) { 6130 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); 6131 } 6132 #endif 6133 } 6134 } 6135 /* Interior face edges have 2 vertices and 2+cells faces */ 6136 for (f = fStart; f < fMax; ++f) { 6137 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}; 6138 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6139 const PetscInt *cone, *coneCell, *orntCell, *support; 6140 PetscInt coneNew[2], coneSize, c, supportSize, s; 6141 6142 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6143 for (r = 0; r < 4; ++r) { 6144 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 6145 6146 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6147 coneNew[1] = newv; 6148 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6149 #if 1 6150 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6151 for (p = 0; p < 2; ++p) { 6152 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); 6153 } 6154 #endif 6155 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6156 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6157 supportRef[0] = fStartNew + (f - fStart)*4 + r; 6158 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 6159 for (s = 0; s < supportSize; ++s) { 6160 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6161 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6162 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6163 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 6164 if (support[s] < cMax) { 6165 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 6166 } else { 6167 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 6168 } 6169 } 6170 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6171 #if 1 6172 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6173 for (p = 0; p < 2+supportSize; ++p) { 6174 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); 6175 } 6176 #endif 6177 } 6178 } 6179 /* Interior cell edges have 2 vertices and 4 faces */ 6180 for (c = cStart; c < cMax; ++c) { 6181 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}; 6182 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 6183 const PetscInt *cone; 6184 PetscInt coneNew[2], supportNew[4]; 6185 6186 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6187 for (r = 0; r < 6; ++r) { 6188 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 6189 6190 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6191 coneNew[1] = newv; 6192 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6193 #if 1 6194 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6195 for (p = 0; p < 2; ++p) { 6196 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); 6197 } 6198 #endif 6199 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 6200 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6201 #if 1 6202 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6203 for (p = 0; p < 4; ++p) { 6204 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); 6205 } 6206 #endif 6207 } 6208 } 6209 /* Hybrid edges have two vertices and the same faces */ 6210 for (e = eMax; e < eEnd; ++e) { 6211 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 6212 const PetscInt *cone, *support, *fcone; 6213 PetscInt coneNew[2], size, fsize, s; 6214 6215 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6216 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6217 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6218 coneNew[0] = vStartNew + (cone[0] - vStart); 6219 coneNew[1] = vStartNew + (cone[1] - vStart); 6220 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6221 #if 1 6222 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6223 for (p = 0; p < 2; ++p) { 6224 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); 6225 } 6226 #endif 6227 for (s = 0; s < size; ++s) { 6228 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6229 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6230 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6231 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 6232 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 6233 } 6234 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6235 #if 1 6236 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6237 for (p = 0; p < size; ++p) { 6238 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); 6239 } 6240 #endif 6241 } 6242 /* Hybrid face edges have 2 vertices and 2+cells faces */ 6243 for (f = fMax; f < fEnd; ++f) { 6244 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 6245 const PetscInt *cone, *support, *ccone, *cornt; 6246 PetscInt coneNew[2], size, csize, s; 6247 6248 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6249 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6250 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6251 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6252 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6253 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6254 #if 1 6255 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6256 for (p = 0; p < 2; ++p) { 6257 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); 6258 } 6259 #endif 6260 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 6261 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 6262 for (s = 0; s < size; ++s) { 6263 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 6264 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 6265 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 6266 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 6267 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]); 6268 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 6269 } 6270 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6271 #if 1 6272 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6273 for (p = 0; p < 2+size; ++p) { 6274 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); 6275 } 6276 #endif 6277 } 6278 /* Hybrid cell edges have 2 vertices and 4 faces */ 6279 for (c = cMax; c < cEnd; ++c) { 6280 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6281 const PetscInt *cone, *support; 6282 PetscInt coneNew[2], size; 6283 6284 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6285 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 6286 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 6287 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6288 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6289 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6290 #if 1 6291 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6292 for (p = 0; p < 2; ++p) { 6293 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); 6294 } 6295 #endif 6296 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 6297 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 6298 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 6299 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 6300 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6301 #if 1 6302 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6303 for (p = 0; p < 4; ++p) { 6304 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); 6305 } 6306 #endif 6307 } 6308 /* Interior vertices have identical supports */ 6309 for (v = vStart; v < vEnd; ++v) { 6310 const PetscInt newp = vStartNew + (v - vStart); 6311 const PetscInt *support, *cone; 6312 PetscInt size, s; 6313 6314 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6315 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6316 for (s = 0; s < size; ++s) { 6317 PetscInt r = 0; 6318 6319 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6320 if (cone[1] == v) r = 1; 6321 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 6322 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 6323 } 6324 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6325 #if 1 6326 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6327 for (p = 0; p < size; ++p) { 6328 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); 6329 } 6330 #endif 6331 } 6332 /* Interior edge vertices have 2 + faces supports */ 6333 for (e = eStart; e < eMax; ++e) { 6334 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6335 const PetscInt *cone, *support; 6336 PetscInt size, s; 6337 6338 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6339 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6340 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6341 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6342 for (s = 0; s < size; ++s) { 6343 PetscInt r; 6344 6345 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6346 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 6347 if (support[s] < fMax) { 6348 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 6349 } else { 6350 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 6351 } 6352 } 6353 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6354 #if 1 6355 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6356 for (p = 0; p < 2+size; ++p) { 6357 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); 6358 } 6359 #endif 6360 } 6361 /* Interior face vertices have 4 + cells supports */ 6362 for (f = fStart; f < fMax; ++f) { 6363 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6364 const PetscInt *cone, *support; 6365 PetscInt size, s; 6366 6367 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6368 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6369 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 6370 for (s = 0; s < size; ++s) { 6371 PetscInt r; 6372 6373 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6374 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 6375 if (support[s] < cMax) { 6376 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 6377 } else { 6378 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 6379 } 6380 } 6381 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6382 #if 1 6383 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6384 for (p = 0; p < 4+size; ++p) { 6385 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); 6386 } 6387 #endif 6388 } 6389 /* Cell vertices have 6 supports */ 6390 for (c = cStart; c < cMax; ++c) { 6391 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 6392 PetscInt supportNew[6]; 6393 6394 for (r = 0; r < 6; ++r) { 6395 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 6396 } 6397 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6398 } 6399 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6400 break; 6401 default: 6402 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6403 } 6404 PetscFunctionReturn(0); 6405 } 6406 6407 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6408 { 6409 PetscSection coordSection, coordSectionNew; 6410 Vec coordinates, coordinatesNew; 6411 PetscScalar *coords, *coordsNew; 6412 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 6413 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 6414 VecType vtype; 6415 PetscErrorCode ierr; 6416 6417 PetscFunctionBegin; 6418 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6419 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6420 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6421 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6422 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6423 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6424 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 6425 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 6426 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 6427 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 6428 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 6429 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 6430 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 6431 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 6432 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 6433 if (cMax < 0) cMax = cEnd; 6434 if (fMax < 0) fMax = fEnd; 6435 if (eMax < 0) eMax = eEnd; 6436 /* All vertices have the spaceDim coordinates */ 6437 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 6438 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 6439 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 6440 } 6441 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 6442 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 6443 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 6444 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 6445 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 6446 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 6447 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 6448 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 6449 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 6450 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 6451 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 6452 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 6453 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 6454 switch (refiner) { 6455 case REFINER_NOOP: break; 6456 case REFINER_SIMPLEX_TO_HEX_3D: 6457 case REFINER_HEX_3D: 6458 case REFINER_HYBRID_HEX_3D: 6459 /* Face vertices have the average of corner coordinates */ 6460 for (f = fStart; f < fMax; ++f) { 6461 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6462 PetscInt *cone = NULL; 6463 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 6464 6465 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6466 for (p = 0; p < closureSize*2; p += 2) { 6467 const PetscInt point = cone[p]; 6468 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6469 } 6470 for (v = 0; v < coneSize; ++v) { 6471 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6472 } 6473 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6474 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6475 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6476 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6477 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6478 } 6479 case REFINER_SIMPLEX_TO_HEX_2D: 6480 case REFINER_HEX_2D: 6481 case REFINER_HYBRID_HEX_2D: 6482 case REFINER_SIMPLEX_1D: 6483 /* Cell vertices have the average of corner coordinates */ 6484 for (c = cStart; c < cMax; ++c) { 6485 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 6486 PetscInt *cone = NULL; 6487 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 6488 6489 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6490 for (p = 0; p < closureSize*2; p += 2) { 6491 const PetscInt point = cone[p]; 6492 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6493 } 6494 for (v = 0; v < coneSize; ++v) { 6495 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6496 } 6497 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6498 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6499 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6500 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6501 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6502 } 6503 case REFINER_SIMPLEX_2D: 6504 case REFINER_HYBRID_SIMPLEX_2D: 6505 case REFINER_SIMPLEX_3D: 6506 case REFINER_HYBRID_SIMPLEX_3D: 6507 /* Edge vertices have the average of endpoint coordinates */ 6508 for (e = eStart; e < eMax; ++e) { 6509 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6510 const PetscInt *cone; 6511 PetscInt coneSize, offA, offB, offnew, d; 6512 6513 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 6514 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 6515 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6516 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 6517 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 6518 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6519 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 6520 for (d = 0; d < spaceDim; ++d) { 6521 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 6522 } 6523 } 6524 /* Old vertices have the same coordinates */ 6525 for (v = vStart; v < vEnd; ++v) { 6526 const PetscInt newv = vStartNew + (v - vStart); 6527 PetscInt off, offnew, d; 6528 6529 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 6530 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6531 for (d = 0; d < spaceDim; ++d) { 6532 coordsNew[offnew+d] = coords[off+d]; 6533 } 6534 } 6535 break; 6536 default: 6537 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6538 } 6539 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 6540 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 6541 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 6542 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 6543 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 6544 if (dm->maxCell) { 6545 const PetscReal *maxCell, *L; 6546 const DMBoundaryType *bd; 6547 ierr = DMGetPeriodicity(dm, &maxCell, &L, &bd);CHKERRQ(ierr); 6548 ierr = DMSetPeriodicity(rdm, maxCell, L, bd);CHKERRQ(ierr); 6549 } 6550 PetscFunctionReturn(0); 6551 } 6552 6553 /*@ 6554 DMPlexCreateProcessSF - Create an SF which just has process connectivity 6555 6556 Collective on DM 6557 6558 Input Parameters: 6559 + dm - The DM 6560 - sfPoint - The PetscSF which encodes point connectivity 6561 6562 Output Parameters: 6563 + processRanks - A list of process neighbors, or NULL 6564 - sfProcess - An SF encoding the process connectivity, or NULL 6565 6566 Level: developer 6567 6568 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 6569 @*/ 6570 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 6571 { 6572 PetscInt numRoots, numLeaves, l; 6573 const PetscInt *localPoints; 6574 const PetscSFNode *remotePoints; 6575 PetscInt *localPointsNew; 6576 PetscSFNode *remotePointsNew; 6577 PetscInt *ranks, *ranksNew; 6578 PetscMPIInt size; 6579 PetscErrorCode ierr; 6580 6581 PetscFunctionBegin; 6582 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6583 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 6584 if (processRanks) {PetscValidPointer(processRanks, 3);} 6585 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 6586 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 6587 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 6588 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 6589 for (l = 0; l < numLeaves; ++l) { 6590 ranks[l] = remotePoints[l].rank; 6591 } 6592 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 6593 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 6594 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 6595 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 6596 for (l = 0; l < numLeaves; ++l) { 6597 ranksNew[l] = ranks[l]; 6598 localPointsNew[l] = l; 6599 remotePointsNew[l].index = 0; 6600 remotePointsNew[l].rank = ranksNew[l]; 6601 } 6602 ierr = PetscFree(ranks);CHKERRQ(ierr); 6603 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 6604 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 6605 if (sfProcess) { 6606 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 6607 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 6608 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 6609 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6610 } 6611 PetscFunctionReturn(0); 6612 } 6613 6614 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6615 { 6616 PetscSF sf, sfNew, sfProcess; 6617 IS processRanks; 6618 MPI_Datatype depthType; 6619 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 6620 const PetscInt *localPoints, *neighbors; 6621 const PetscSFNode *remotePoints; 6622 PetscInt *localPointsNew; 6623 PetscSFNode *remotePointsNew; 6624 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 6625 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 6626 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6627 PetscErrorCode ierr; 6628 6629 PetscFunctionBegin; 6630 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 6631 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 6632 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 6633 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth); 6634 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6635 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6636 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6637 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6638 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6639 cMax = cMax < 0 ? cEnd : cMax; 6640 fMax = fMax < 0 ? fEnd : fMax; 6641 eMax = eMax < 0 ? eEnd : eMax; 6642 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6643 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 6644 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 6645 /* Calculate size of new SF */ 6646 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 6647 if (numRoots < 0) PetscFunctionReturn(0); 6648 for (l = 0; l < numLeaves; ++l) { 6649 const PetscInt p = localPoints[l]; 6650 6651 switch (refiner) { 6652 case REFINER_SIMPLEX_1D: 6653 if ((p >= vStart) && (p < vEnd)) { 6654 /* Interior vertices stay the same */ 6655 ++numLeavesNew; 6656 } else if ((p >= cStart && p < cMax)) { 6657 /* Interior cells add new cells and interior vertices */ 6658 numLeavesNew += 2 + 1; 6659 } 6660 break; 6661 case REFINER_SIMPLEX_2D: 6662 case REFINER_HYBRID_SIMPLEX_2D: 6663 if ((p >= vStart) && (p < vEnd)) { 6664 /* Interior vertices stay the same */ 6665 ++numLeavesNew; 6666 } else if ((p >= fStart) && (p < fMax)) { 6667 /* Interior faces add new faces and vertex */ 6668 numLeavesNew += 2 + 1; 6669 } else if ((p >= fMax) && (p < fEnd)) { 6670 /* Hybrid faces stay the same */ 6671 ++numLeavesNew; 6672 } else if ((p >= cStart) && (p < cMax)) { 6673 /* Interior cells add new cells and interior faces */ 6674 numLeavesNew += 4 + 3; 6675 } else if ((p >= cMax) && (p < cEnd)) { 6676 /* Hybrid cells add new cells and hybrid face */ 6677 numLeavesNew += 2 + 1; 6678 } 6679 break; 6680 case REFINER_SIMPLEX_TO_HEX_2D: 6681 if ((p >= vStart) && (p < vEnd)) { 6682 /* Interior vertices stay the same */ 6683 ++numLeavesNew; 6684 } else if ((p >= fStart) && (p < fEnd)) { 6685 /* Interior faces add new faces and vertex */ 6686 numLeavesNew += 2 + 1; 6687 } else if ((p >= cStart) && (p < cEnd)) { 6688 /* Interior cells add new cells, interior faces, and vertex */ 6689 numLeavesNew += 3 + 3 + 1; 6690 } 6691 break; 6692 case REFINER_HEX_2D: 6693 case REFINER_HYBRID_HEX_2D: 6694 if ((p >= vStart) && (p < vEnd)) { 6695 /* Interior vertices stay the same */ 6696 ++numLeavesNew; 6697 } else if ((p >= fStart) && (p < fMax)) { 6698 /* Interior faces add new faces and vertex */ 6699 numLeavesNew += 2 + 1; 6700 } else if ((p >= fMax) && (p < fEnd)) { 6701 /* Hybrid faces stay the same */ 6702 ++numLeavesNew; 6703 } else if ((p >= cStart) && (p < cMax)) { 6704 /* Interior cells add new cells, interior faces, and vertex */ 6705 numLeavesNew += 4 + 4 + 1; 6706 } else if ((p >= cMax) && (p < cEnd)) { 6707 /* Hybrid cells add new cells and hybrid face */ 6708 numLeavesNew += 2 + 1; 6709 } 6710 break; 6711 case REFINER_SIMPLEX_3D: 6712 case REFINER_HYBRID_SIMPLEX_3D: 6713 if ((p >= vStart) && (p < vEnd)) { 6714 /* Interior vertices stay the same */ 6715 ++numLeavesNew; 6716 } else if ((p >= eStart) && (p < eMax)) { 6717 /* Interior edges add new edges and vertex */ 6718 numLeavesNew += 2 + 1; 6719 } else if ((p >= eMax) && (p < eEnd)) { 6720 /* Hybrid edges stay the same */ 6721 ++numLeavesNew; 6722 } else if ((p >= fStart) && (p < fMax)) { 6723 /* Interior faces add new faces and edges */ 6724 numLeavesNew += 4 + 3; 6725 } else if ((p >= fMax) && (p < fEnd)) { 6726 /* Hybrid faces add new faces and edges */ 6727 numLeavesNew += 2 + 1; 6728 } else if ((p >= cStart) && (p < cMax)) { 6729 /* Interior cells add new cells, faces, and edges */ 6730 numLeavesNew += 8 + 8 + 1; 6731 } else if ((p >= cMax) && (p < cEnd)) { 6732 /* Hybrid cells add new cells and faces */ 6733 numLeavesNew += 4 + 3; 6734 } 6735 break; 6736 case REFINER_SIMPLEX_TO_HEX_3D: 6737 if ((p >= vStart) && (p < vEnd)) { 6738 /* Interior vertices stay the same */ 6739 ++numLeavesNew; 6740 } else if ((p >= eStart) && (p < eEnd)) { 6741 /* Interior edges add new edges and vertex */ 6742 numLeavesNew += 2 + 1; 6743 } else if ((p >= fStart) && (p < fEnd)) { 6744 /* Interior faces add new faces, edges and a vertex */ 6745 numLeavesNew += 3 + 3 + 1; 6746 } else if ((p >= cStart) && (p < cEnd)) { 6747 /* Interior cells add new cells, faces, edges and a vertex */ 6748 numLeavesNew += 4 + 6 + 4 + 1; 6749 } 6750 break; 6751 case REFINER_HEX_3D: 6752 case REFINER_HYBRID_HEX_3D: 6753 if ((p >= vStart) && (p < vEnd)) { 6754 /* Old vertices stay the same */ 6755 ++numLeavesNew; 6756 } else if ((p >= eStart) && (p < eMax)) { 6757 /* Interior edges add new edges, and vertex */ 6758 numLeavesNew += 2 + 1; 6759 } else if ((p >= eMax) && (p < eEnd)) { 6760 /* Hybrid edges stay the same */ 6761 ++numLeavesNew; 6762 } else if ((p >= fStart) && (p < fMax)) { 6763 /* Interior faces add new faces, edges, and vertex */ 6764 numLeavesNew += 4 + 4 + 1; 6765 } else if ((p >= fMax) && (p < fEnd)) { 6766 /* Hybrid faces add new faces and edges */ 6767 numLeavesNew += 2 + 1; 6768 } else if ((p >= cStart) && (p < cMax)) { 6769 /* Interior cells add new cells, faces, edges, and vertex */ 6770 numLeavesNew += 8 + 12 + 6 + 1; 6771 } else if ((p >= cStart) && (p < cEnd)) { 6772 /* Hybrid cells add new cells, faces, and edges */ 6773 numLeavesNew += 4 + 4 + 1; 6774 } 6775 break; 6776 default: 6777 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6778 } 6779 } 6780 /* Communicate depthSizes for each remote rank */ 6781 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 6782 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 6783 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 6784 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 6785 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 6786 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 6787 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 6788 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 6789 for (n = 0; n < numNeighbors; ++n) { 6790 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 6791 } 6792 depthSizeOld[depth] = cMax; 6793 depthSizeOld[0] = vMax; 6794 depthSizeOld[depth-1] = fMax; 6795 depthSizeOld[1] = eMax; 6796 6797 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 6798 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 6799 6800 depthSizeOld[depth] = cEnd - cStart; 6801 depthSizeOld[0] = vEnd - vStart; 6802 depthSizeOld[depth-1] = fEnd - fStart; 6803 depthSizeOld[1] = eEnd - eStart; 6804 6805 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 6806 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 6807 for (n = 0; n < numNeighbors; ++n) { 6808 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 6809 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 6810 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]; 6811 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 6812 } 6813 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 6814 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 6815 /* Calculate new point SF */ 6816 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 6817 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 6818 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 6819 for (l = 0, m = 0; l < numLeaves; ++l) { 6820 PetscInt p = localPoints[l]; 6821 PetscInt rp = remotePoints[l].index, n; 6822 PetscMPIInt rrank = remotePoints[l].rank; 6823 6824 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 6825 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 6826 switch (refiner) { 6827 case REFINER_SIMPLEX_1D: 6828 if ((p >= vStart) && (p < vEnd)) { 6829 /* Old vertices stay the same */ 6830 localPointsNew[m] = vStartNew + (p - vStart); 6831 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6832 remotePointsNew[m].rank = rrank; 6833 ++m; 6834 } else if ((p >= cStart) && (p < cMax)) { 6835 /* Old interior cells add new cells and vertex */ 6836 for (r = 0; r < 2; ++r, ++m) { 6837 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 6838 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 6839 remotePointsNew[m].rank = rrank; 6840 } 6841 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 6842 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 6843 remotePointsNew[m].rank = rrank; 6844 ++m; 6845 } 6846 break; 6847 case REFINER_SIMPLEX_2D: 6848 case REFINER_HYBRID_SIMPLEX_2D: 6849 if ((p >= vStart) && (p < vEnd)) { 6850 /* Old vertices stay the same */ 6851 localPointsNew[m] = vStartNew + (p - vStart); 6852 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6853 remotePointsNew[m].rank = rrank; 6854 ++m; 6855 } else if ((p >= fStart) && (p < fMax)) { 6856 /* Old interior faces add new faces and vertex */ 6857 for (r = 0; r < 2; ++r, ++m) { 6858 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 6859 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 6860 remotePointsNew[m].rank = rrank; 6861 } 6862 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 6863 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 6864 remotePointsNew[m].rank = rrank; 6865 ++m; 6866 } else if ((p >= fMax) && (p < fEnd)) { 6867 /* Old hybrid faces stay the same */ 6868 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 6869 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 6870 remotePointsNew[m].rank = rrank; 6871 ++m; 6872 } else if ((p >= cStart) && (p < cMax)) { 6873 /* Old interior cells add new cells and interior faces */ 6874 for (r = 0; r < 4; ++r, ++m) { 6875 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 6876 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 6877 remotePointsNew[m].rank = rrank; 6878 } 6879 for (r = 0; r < 3; ++r, ++m) { 6880 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 6881 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 6882 remotePointsNew[m].rank = rrank; 6883 } 6884 } else if ((p >= cMax) && (p < cEnd)) { 6885 /* Old hybrid cells add new cells and hybrid face */ 6886 for (r = 0; r < 2; ++r, ++m) { 6887 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 6888 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 6889 remotePointsNew[m].rank = rrank; 6890 } 6891 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6892 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]); 6893 remotePointsNew[m].rank = rrank; 6894 ++m; 6895 } 6896 break; 6897 case REFINER_SIMPLEX_TO_HEX_2D: 6898 if ((p >= vStart) && (p < vEnd)) { 6899 /* Old vertices stay the same */ 6900 localPointsNew[m] = vStartNew + (p - vStart); 6901 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6902 remotePointsNew[m].rank = rrank; 6903 ++m; 6904 } else if ((p >= fStart) && (p < fEnd)) { 6905 /* Old interior faces add new faces and vertex */ 6906 for (r = 0; r < 2; ++r, ++m) { 6907 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 6908 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 6909 remotePointsNew[m].rank = rrank; 6910 } 6911 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 6912 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 6913 remotePointsNew[m].rank = rrank; 6914 ++m; 6915 } else if ((p >= cStart) && (p < cEnd)) { 6916 /* Old interior cells add new cells, interior faces, and a vertex */ 6917 for (r = 0; r < 3; ++r, ++m) { 6918 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 6919 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 6920 remotePointsNew[m].rank = rrank; 6921 } 6922 for (r = 0; r < 3; ++r, ++m) { 6923 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6924 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 6925 remotePointsNew[m].rank = rrank; 6926 } 6927 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6928 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 6929 remotePointsNew[m].rank = rrank; 6930 ++m; 6931 } 6932 break; 6933 case REFINER_HEX_2D: 6934 case REFINER_HYBRID_HEX_2D: 6935 if ((p >= vStart) && (p < vEnd)) { 6936 /* Old vertices stay the same */ 6937 localPointsNew[m] = vStartNew + (p - vStart); 6938 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6939 remotePointsNew[m].rank = rrank; 6940 ++m; 6941 } else if ((p >= fStart) && (p < fMax)) { 6942 /* Old interior faces add new faces and vertex */ 6943 for (r = 0; r < 2; ++r, ++m) { 6944 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 6945 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 6946 remotePointsNew[m].rank = rrank; 6947 } 6948 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 6949 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 6950 remotePointsNew[m].rank = rrank; 6951 ++m; 6952 } else if ((p >= fMax) && (p < fEnd)) { 6953 /* Old hybrid faces stay the same */ 6954 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 6955 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 6956 remotePointsNew[m].rank = rrank; 6957 ++m; 6958 } else if ((p >= cStart) && (p < cMax)) { 6959 /* Old interior cells add new cells, interior faces, and vertex */ 6960 for (r = 0; r < 4; ++r, ++m) { 6961 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 6962 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 6963 remotePointsNew[m].rank = rrank; 6964 } 6965 for (r = 0; r < 4; ++r, ++m) { 6966 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 6967 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 6968 remotePointsNew[m].rank = rrank; 6969 } 6970 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 6971 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 6972 remotePointsNew[m].rank = rrank; 6973 ++m; 6974 } else if ((p >= cStart) && (p < cMax)) { 6975 /* Old hybrid cells add new cells and hybrid face */ 6976 for (r = 0; r < 2; ++r, ++m) { 6977 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 6978 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 6979 remotePointsNew[m].rank = rrank; 6980 } 6981 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6982 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]); 6983 remotePointsNew[m].rank = rrank; 6984 ++m; 6985 } 6986 break; 6987 case REFINER_SIMPLEX_3D: 6988 case REFINER_HYBRID_SIMPLEX_3D: 6989 if ((p >= vStart) && (p < vEnd)) { 6990 /* Interior vertices stay the same */ 6991 localPointsNew[m] = vStartNew + (p - vStart); 6992 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6993 remotePointsNew[m].rank = rrank; 6994 ++m; 6995 } else if ((p >= eStart) && (p < eMax)) { 6996 /* Interior edges add new edges and vertex */ 6997 for (r = 0; r < 2; ++r, ++m) { 6998 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6999 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7000 remotePointsNew[m].rank = rrank; 7001 } 7002 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7003 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7004 remotePointsNew[m].rank = rrank; 7005 ++m; 7006 } else if ((p >= eMax) && (p < eEnd)) { 7007 /* Hybrid edges stay the same */ 7008 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 7009 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]); 7010 remotePointsNew[m].rank = rrank; 7011 ++m; 7012 } else if ((p >= fStart) && (p < fMax)) { 7013 /* Interior faces add new faces and edges */ 7014 for (r = 0; r < 4; ++r, ++m) { 7015 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7016 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7017 remotePointsNew[m].rank = rrank; 7018 } 7019 for (r = 0; r < 3; ++r, ++m) { 7020 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 7021 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 7022 remotePointsNew[m].rank = rrank; 7023 } 7024 } else if ((p >= fMax) && (p < fEnd)) { 7025 /* Hybrid faces add new faces and edges */ 7026 for (r = 0; r < 2; ++r, ++m) { 7027 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 7028 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; 7029 remotePointsNew[m].rank = rrank; 7030 } 7031 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 7032 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]); 7033 remotePointsNew[m].rank = rrank; 7034 ++m; 7035 } else if ((p >= cStart) && (p < cMax)) { 7036 /* Interior cells add new cells, faces, and edges */ 7037 for (r = 0; r < 8; ++r, ++m) { 7038 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7039 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7040 remotePointsNew[m].rank = rrank; 7041 } 7042 for (r = 0; r < 8; ++r, ++m) { 7043 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 7044 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 7045 remotePointsNew[m].rank = rrank; 7046 } 7047 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 7048 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; 7049 remotePointsNew[m].rank = rrank; 7050 ++m; 7051 } else if ((p >= cMax) && (p < cEnd)) { 7052 /* Hybrid cells add new cells and faces */ 7053 for (r = 0; r < 4; ++r, ++m) { 7054 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7055 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7056 remotePointsNew[m].rank = rrank; 7057 } 7058 for (r = 0; r < 3; ++r, ++m) { 7059 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 7060 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; 7061 remotePointsNew[m].rank = rrank; 7062 } 7063 } 7064 break; 7065 case REFINER_SIMPLEX_TO_HEX_3D: 7066 if ((p >= vStart) && (p < vEnd)) { 7067 /* Interior vertices stay the same */ 7068 localPointsNew[m] = vStartNew + (p - vStart); 7069 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7070 remotePointsNew[m].rank = rrank; 7071 ++m; 7072 } else if ((p >= eStart) && (p < eEnd)) { 7073 /* Interior edges add new edges and vertex */ 7074 for (r = 0; r < 2; ++r, ++m) { 7075 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7076 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7077 remotePointsNew[m].rank = rrank; 7078 } 7079 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7080 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7081 remotePointsNew[m].rank = rrank; 7082 ++m; 7083 } else if ((p >= fStart) && (p < fEnd)) { 7084 /* Interior faces add new faces, edges and a vertex */ 7085 for (r = 0; r < 3; ++r, ++m) { 7086 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 7087 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 7088 remotePointsNew[m].rank = rrank; 7089 } 7090 for (r = 0; r < 3; ++r, ++m) { 7091 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 7092 remotePointsNew[m].index = reStartNew[n] + (rdepthSizeOld[n*(depth+1)+1])*2 + (rp - rfStart[n])*3 + r; 7093 remotePointsNew[m].rank = rrank; 7094 } 7095 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 7096 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 7097 remotePointsNew[m].rank = rrank; 7098 ++m; 7099 } else if ((p >= cStart) && (p < cEnd)) { 7100 /* Interior cells add new cells, faces, edges, and a vertex */ 7101 for (r = 0; r < 4; ++r, ++m) { 7102 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7103 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7104 remotePointsNew[m].rank = rrank; 7105 } 7106 for (r = 0; r < 6; ++r, ++m) { 7107 localPointsNew[m] = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 7108 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*6 + r; 7109 remotePointsNew[m].rank = rrank; 7110 } 7111 for (r = 0; r < 4; ++r, ++m) { 7112 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 7113 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*4 + r; 7114 remotePointsNew[m].rank = rrank; 7115 } 7116 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 7117 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 7118 remotePointsNew[m].rank = rrank; 7119 ++m; 7120 } 7121 break; 7122 case REFINER_HEX_3D: 7123 case REFINER_HYBRID_HEX_3D: 7124 if ((p >= vStart) && (p < vEnd)) { 7125 /* Interior vertices stay the same */ 7126 localPointsNew[m] = vStartNew + (p - vStart); 7127 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7128 remotePointsNew[m].rank = rrank; 7129 ++m; 7130 } else if ((p >= eStart) && (p < eMax)) { 7131 /* Interior edges add new edges and vertex */ 7132 for (r = 0; r < 2; ++r, ++m) { 7133 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7134 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7135 remotePointsNew[m].rank = rrank; 7136 } 7137 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7138 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7139 remotePointsNew[m].rank = rrank; 7140 ++m; 7141 } else if ((p >= eMax) && (p < eEnd)) { 7142 /* Hybrid edges stay the same */ 7143 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 7144 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]); 7145 remotePointsNew[m].rank = rrank; 7146 ++m; 7147 } else if ((p >= fStart) && (p < fMax)) { 7148 /* Interior faces add new faces, edges, and vertex */ 7149 for (r = 0; r < 4; ++r, ++m) { 7150 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7151 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7152 remotePointsNew[m].rank = rrank; 7153 } 7154 for (r = 0; r < 4; ++r, ++m) { 7155 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 7156 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 7157 remotePointsNew[m].rank = rrank; 7158 } 7159 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 7160 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 7161 remotePointsNew[m].rank = rrank; 7162 ++m; 7163 } else if ((p >= fMax) && (p < fEnd)) { 7164 /* Hybrid faces add new faces and edges */ 7165 for (r = 0; r < 2; ++r, ++m) { 7166 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 7167 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; 7168 remotePointsNew[m].rank = rrank; 7169 } 7170 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 7171 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]); 7172 remotePointsNew[m].rank = rrank; 7173 ++m; 7174 } else if ((p >= cStart) && (p < cMax)) { 7175 /* Interior cells add new cells, faces, edges, and vertex */ 7176 for (r = 0; r < 8; ++r, ++m) { 7177 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7178 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7179 remotePointsNew[m].rank = rrank; 7180 } 7181 for (r = 0; r < 12; ++r, ++m) { 7182 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 7183 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 7184 remotePointsNew[m].rank = rrank; 7185 } 7186 for (r = 0; r < 6; ++r, ++m) { 7187 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 7188 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; 7189 remotePointsNew[m].rank = rrank; 7190 } 7191 for (r = 0; r < 1; ++r, ++m) { 7192 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 7193 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 7194 remotePointsNew[m].rank = rrank; 7195 } 7196 } else if ((p >= cMax) && (p < cEnd)) { 7197 /* Hybrid cells add new cells, faces, and edges */ 7198 for (r = 0; r < 4; ++r, ++m) { 7199 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7200 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7201 remotePointsNew[m].rank = rrank; 7202 } 7203 for (r = 0; r < 4; ++r, ++m) { 7204 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 7205 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; 7206 remotePointsNew[m].rank = rrank; 7207 } 7208 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 7209 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]); 7210 remotePointsNew[m].rank = rrank; 7211 ++m; 7212 } 7213 break; 7214 default: 7215 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7216 } 7217 } 7218 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 7219 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 7220 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 7221 { 7222 PetscSFNode *rp, *rtmp; 7223 PetscInt *lp, *idx, *ltmp, i; 7224 7225 /* SF needs sorted leaves to correct calculate Gather */ 7226 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 7227 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 7228 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 7229 for (i = 0; i < numLeavesNew; ++i) { 7230 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); 7231 idx[i] = i; 7232 } 7233 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 7234 for (i = 0; i < numLeavesNew; ++i) { 7235 lp[i] = localPointsNew[idx[i]]; 7236 rp[i] = remotePointsNew[idx[i]]; 7237 } 7238 ltmp = localPointsNew; 7239 localPointsNew = lp; 7240 rtmp = remotePointsNew; 7241 remotePointsNew = rp; 7242 ierr = PetscFree(idx);CHKERRQ(ierr); 7243 ierr = PetscFree(ltmp);CHKERRQ(ierr); 7244 ierr = PetscFree(rtmp);CHKERRQ(ierr); 7245 } 7246 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 7247 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 7248 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 7249 PetscFunctionReturn(0); 7250 } 7251 7252 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 7253 { 7254 PetscInt numLabels, l; 7255 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 7256 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7257 PetscErrorCode ierr; 7258 7259 PetscFunctionBegin; 7260 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7261 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 7262 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7263 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7264 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 7265 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7266 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 7267 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7268 switch (refiner) { 7269 case REFINER_NOOP: 7270 case REFINER_SIMPLEX_1D: 7271 case REFINER_SIMPLEX_2D: 7272 case REFINER_SIMPLEX_TO_HEX_2D: 7273 case REFINER_HEX_2D: 7274 case REFINER_SIMPLEX_3D: 7275 case REFINER_HEX_3D: 7276 case REFINER_SIMPLEX_TO_HEX_3D: 7277 break; 7278 case REFINER_HYBRID_SIMPLEX_3D: 7279 case REFINER_HYBRID_HEX_3D: 7280 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 7281 case REFINER_HYBRID_SIMPLEX_2D: 7282 case REFINER_HYBRID_HEX_2D: 7283 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 7284 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 7285 break; 7286 default: 7287 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7288 } 7289 for (l = 0; l < numLabels; ++l) { 7290 DMLabel label, labelNew; 7291 const char *lname; 7292 PetscBool isDepth; 7293 IS valueIS; 7294 const PetscInt *values; 7295 PetscInt defVal; 7296 PetscInt numValues, val; 7297 7298 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 7299 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 7300 if (isDepth) continue; 7301 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 7302 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 7303 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 7304 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 7305 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 7306 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 7307 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 7308 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 7309 for (val = 0; val < numValues; ++val) { 7310 IS pointIS; 7311 const PetscInt *points; 7312 PetscInt numPoints, n; 7313 7314 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 7315 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 7316 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 7317 /* Ensure refined label is created with same number of strata as 7318 * original (even if no entries here). */ 7319 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 7320 for (n = 0; n < numPoints; ++n) { 7321 const PetscInt p = points[n]; 7322 switch (refiner) { 7323 case REFINER_SIMPLEX_1D: 7324 if ((p >= vStart) && (p < vEnd)) { 7325 /* Old vertices stay the same */ 7326 newp = vStartNew + (p - vStart); 7327 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7328 } else if ((p >= cStart) && (p < cEnd)) { 7329 /* Old cells add new cells and vertex */ 7330 newp = vStartNew + (vEnd - vStart) + (p - cStart); 7331 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7332 for (r = 0; r < 2; ++r) { 7333 newp = cStartNew + (p - cStart)*2 + r; 7334 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7335 } 7336 } 7337 break; 7338 case REFINER_SIMPLEX_2D: 7339 if ((p >= vStart) && (p < vEnd)) { 7340 /* Old vertices stay the same */ 7341 newp = vStartNew + (p - vStart); 7342 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7343 } else if ((p >= fStart) && (p < fEnd)) { 7344 /* Old faces add new faces and vertex */ 7345 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7346 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7347 for (r = 0; r < 2; ++r) { 7348 newp = fStartNew + (p - fStart)*2 + r; 7349 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7350 } 7351 } else if ((p >= cStart) && (p < cEnd)) { 7352 /* Old cells add new cells and interior faces */ 7353 for (r = 0; r < 4; ++r) { 7354 newp = cStartNew + (p - cStart)*4 + r; 7355 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7356 } 7357 for (r = 0; r < 3; ++r) { 7358 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7359 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7360 } 7361 } 7362 break; 7363 case REFINER_SIMPLEX_TO_HEX_2D: 7364 if ((p >= vStart) && (p < vEnd)) { 7365 /* Old vertices stay the same */ 7366 newp = vStartNew + (p - vStart); 7367 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7368 } else if ((p >= fStart) && (p < fEnd)) { 7369 /* Old faces add new faces and vertex */ 7370 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7371 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7372 for (r = 0; r < 2; ++r) { 7373 newp = fStartNew + (p - fStart)*2 + r; 7374 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7375 } 7376 } else if ((p >= cStart) && (p < cEnd)) { 7377 /* Old cells add new cells, interior faces, and a vertex */ 7378 for (r = 0; r < 3; ++r) { 7379 newp = cStartNew + (p - cStart)*3 + r; 7380 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7381 } 7382 for (r = 0; r < 3; ++r) { 7383 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7384 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7385 } 7386 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 7387 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7388 } 7389 break; 7390 case REFINER_HEX_2D: 7391 if ((p >= vStart) && (p < vEnd)) { 7392 /* Old vertices stay the same */ 7393 newp = vStartNew + (p - vStart); 7394 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7395 } else if ((p >= fStart) && (p < fEnd)) { 7396 /* Old faces add new faces and vertex */ 7397 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7398 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7399 for (r = 0; r < 2; ++r) { 7400 newp = fStartNew + (p - fStart)*2 + r; 7401 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7402 } 7403 } else if ((p >= cStart) && (p < cEnd)) { 7404 /* Old cells add new cells and interior faces and vertex */ 7405 for (r = 0; r < 4; ++r) { 7406 newp = cStartNew + (p - cStart)*4 + r; 7407 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7408 } 7409 for (r = 0; r < 4; ++r) { 7410 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 7411 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7412 } 7413 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7414 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7415 } 7416 break; 7417 case REFINER_HYBRID_SIMPLEX_2D: 7418 if ((p >= vStart) && (p < vEnd)) { 7419 /* Old vertices stay the same */ 7420 newp = vStartNew + (p - vStart); 7421 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7422 } else if ((p >= fStart) && (p < fMax)) { 7423 /* Old interior faces add new faces and vertex */ 7424 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7425 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7426 for (r = 0; r < 2; ++r) { 7427 newp = fStartNew + (p - fStart)*2 + r; 7428 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7429 } 7430 } else if ((p >= fMax) && (p < fEnd)) { 7431 /* Old hybrid faces stay the same */ 7432 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 7433 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7434 } else if ((p >= cStart) && (p < cMax)) { 7435 /* Old interior cells add new cells and interior faces */ 7436 for (r = 0; r < 4; ++r) { 7437 newp = cStartNew + (p - cStart)*4 + r; 7438 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7439 } 7440 for (r = 0; r < 3; ++r) { 7441 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7442 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7443 } 7444 } else if ((p >= cMax) && (p < cEnd)) { 7445 /* Old hybrid cells add new cells and hybrid face */ 7446 for (r = 0; r < 2; ++r) { 7447 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 7448 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7449 } 7450 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 7451 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7452 } 7453 break; 7454 case REFINER_HYBRID_HEX_2D: 7455 if ((p >= vStart) && (p < vEnd)) { 7456 /* Old vertices stay the same */ 7457 newp = vStartNew + (p - vStart); 7458 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7459 } else if ((p >= fStart) && (p < fMax)) { 7460 /* Old interior faces add new faces and vertex */ 7461 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7462 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7463 for (r = 0; r < 2; ++r) { 7464 newp = fStartNew + (p - fStart)*2 + r; 7465 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7466 } 7467 } else if ((p >= fMax) && (p < fEnd)) { 7468 /* Old hybrid faces stay the same */ 7469 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 7470 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7471 } else if ((p >= cStart) && (p < cMax)) { 7472 /* Old interior cells add new cells, interior faces, and vertex */ 7473 for (r = 0; r < 4; ++r) { 7474 newp = cStartNew + (p - cStart)*4 + r; 7475 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7476 } 7477 for (r = 0; r < 4; ++r) { 7478 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 7479 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7480 } 7481 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7482 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7483 } else if ((p >= cMax) && (p < cEnd)) { 7484 /* Old hybrid cells add new cells and hybrid face */ 7485 for (r = 0; r < 2; ++r) { 7486 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 7487 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7488 } 7489 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 7490 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7491 } 7492 break; 7493 case REFINER_SIMPLEX_3D: 7494 if ((p >= vStart) && (p < vEnd)) { 7495 /* Old vertices stay the same */ 7496 newp = vStartNew + (p - vStart); 7497 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7498 } else if ((p >= eStart) && (p < eEnd)) { 7499 /* Old edges add new edges and vertex */ 7500 for (r = 0; r < 2; ++r) { 7501 newp = eStartNew + (p - eStart)*2 + r; 7502 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7503 } 7504 newp = vStartNew + (vEnd - vStart) + (p - eStart); 7505 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7506 } else if ((p >= fStart) && (p < fEnd)) { 7507 /* Old faces add new faces and edges */ 7508 for (r = 0; r < 4; ++r) { 7509 newp = fStartNew + (p - fStart)*4 + r; 7510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7511 } 7512 for (r = 0; r < 3; ++r) { 7513 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 7514 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7515 } 7516 } else if ((p >= cStart) && (p < cEnd)) { 7517 /* Old cells add new cells and interior faces and edges */ 7518 for (r = 0; r < 8; ++r) { 7519 newp = cStartNew + (p - cStart)*8 + r; 7520 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7521 } 7522 for (r = 0; r < 8; ++r) { 7523 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 7524 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7525 } 7526 for (r = 0; r < 1; ++r) { 7527 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 7528 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7529 } 7530 } 7531 break; 7532 case REFINER_SIMPLEX_TO_HEX_3D: 7533 if ((p >= vStart) && (p < vEnd)) { 7534 /* Old vertices stay the same */ 7535 newp = vStartNew + (p - vStart); 7536 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7537 } else if ((p >= eStart) && (p < eEnd)) { 7538 /* Old edges add new edges and vertex */ 7539 for (r = 0; r < 2; ++r) { 7540 newp = eStartNew + (p - eStart)*2 + r; 7541 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7542 } 7543 newp = vStartNew + (vEnd - vStart) + (p - eStart); 7544 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7545 } else if ((p >= fStart) && (p < fEnd)) { 7546 /* Old faces add new faces, edges and a vertex */ 7547 for (r = 0; r < 3; ++r) { 7548 newp = fStartNew + (p - fStart)*3 + r; 7549 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7550 } 7551 for (r = 0; r < 3; ++r) { 7552 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 7553 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7554 } 7555 } else if ((p >= cStart) && (p < cEnd)) { 7556 /* Old cells add new cells and interior faces and edges and a vertex */ 7557 for (r = 0; r < 4; ++r) { 7558 newp = cStartNew + (p - cStart)*4 + r; 7559 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7560 } 7561 for (r = 0; r < 6; ++r) { 7562 newp = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 7563 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7564 } 7565 for (r = 0; r < 4; ++r) { 7566 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 7567 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7568 } 7569 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + p - cStart; 7570 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7571 } 7572 break; 7573 case REFINER_HYBRID_SIMPLEX_3D: 7574 if ((p >= vStart) && (p < vEnd)) { 7575 /* Interior vertices stay the same */ 7576 newp = vStartNew + (p - vStart); 7577 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7578 } else if ((p >= eStart) && (p < eMax)) { 7579 /* Interior edges add new edges and vertex */ 7580 for (r = 0; r < 2; ++r) { 7581 newp = eStartNew + (p - eStart)*2 + r; 7582 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7583 } 7584 newp = vStartNew + (vEnd - vStart) + (p - eStart); 7585 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7586 } else if ((p >= eMax) && (p < eEnd)) { 7587 /* Hybrid edges stay the same */ 7588 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 7589 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7590 } else if ((p >= fStart) && (p < fMax)) { 7591 /* Interior faces add new faces and edges */ 7592 for (r = 0; r < 4; ++r) { 7593 newp = fStartNew + (p - fStart)*4 + r; 7594 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7595 } 7596 for (r = 0; r < 3; ++r) { 7597 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 7598 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7599 } 7600 } else if ((p >= fMax) && (p < fEnd)) { 7601 /* Hybrid faces add new faces and edges */ 7602 for (r = 0; r < 2; ++r) { 7603 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 7604 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7605 } 7606 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 7607 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7608 } else if ((p >= cStart) && (p < cMax)) { 7609 /* Interior cells add new cells, faces, and edges */ 7610 for (r = 0; r < 8; ++r) { 7611 newp = cStartNew + (p - cStart)*8 + r; 7612 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7613 } 7614 for (r = 0; r < 8; ++r) { 7615 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 7616 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7617 } 7618 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 7619 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7620 } else if ((p >= cMax) && (p < cEnd)) { 7621 /* Hybrid cells add new cells and faces */ 7622 for (r = 0; r < 4; ++r) { 7623 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7624 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7625 } 7626 for (r = 0; r < 3; ++r) { 7627 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 7628 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7629 } 7630 } 7631 break; 7632 case REFINER_HEX_3D: 7633 if ((p >= vStart) && (p < vEnd)) { 7634 /* Old vertices stay the same */ 7635 newp = vStartNew + (p - vStart); 7636 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7637 } else if ((p >= eStart) && (p < eEnd)) { 7638 /* Old edges add new edges and vertex */ 7639 for (r = 0; r < 2; ++r) { 7640 newp = eStartNew + (p - eStart)*2 + r; 7641 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7642 } 7643 newp = vStartNew + (vEnd - vStart) + (p - eStart); 7644 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7645 } else if ((p >= fStart) && (p < fEnd)) { 7646 /* Old faces add new faces, edges, and vertex */ 7647 for (r = 0; r < 4; ++r) { 7648 newp = fStartNew + (p - fStart)*4 + r; 7649 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7650 } 7651 for (r = 0; r < 4; ++r) { 7652 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 7653 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7654 } 7655 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 7656 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7657 } else if ((p >= cStart) && (p < cEnd)) { 7658 /* Old cells add new cells, faces, edges, and vertex */ 7659 for (r = 0; r < 8; ++r) { 7660 newp = cStartNew + (p - cStart)*8 + r; 7661 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7662 } 7663 for (r = 0; r < 12; ++r) { 7664 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 7665 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7666 } 7667 for (r = 0; r < 6; ++r) { 7668 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 7669 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7670 } 7671 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 7672 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7673 } 7674 break; 7675 case REFINER_HYBRID_HEX_3D: 7676 if ((p >= vStart) && (p < vEnd)) { 7677 /* Interior vertices stay the same */ 7678 newp = vStartNew + (p - vStart); 7679 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7680 } else if ((p >= eStart) && (p < eMax)) { 7681 /* Interior edges add new edges and vertex */ 7682 for (r = 0; r < 2; ++r) { 7683 newp = eStartNew + (p - eStart)*2 + r; 7684 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7685 } 7686 newp = vStartNew + (vEnd - vStart) + (p - eStart); 7687 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7688 } else if ((p >= eMax) && (p < eEnd)) { 7689 /* Hybrid edges stay the same */ 7690 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 7691 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7692 } else if ((p >= fStart) && (p < fMax)) { 7693 /* Interior faces add new faces, edges, and vertex */ 7694 for (r = 0; r < 4; ++r) { 7695 newp = fStartNew + (p - fStart)*4 + r; 7696 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7697 } 7698 for (r = 0; r < 4; ++r) { 7699 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 7700 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7701 } 7702 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 7703 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7704 } else if ((p >= fMax) && (p < fEnd)) { 7705 /* Hybrid faces add new faces and edges */ 7706 for (r = 0; r < 2; ++r) { 7707 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 7708 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7709 } 7710 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 7711 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7712 } else if ((p >= cStart) && (p < cMax)) { 7713 /* Interior cells add new cells, faces, edges, and vertex */ 7714 for (r = 0; r < 8; ++r) { 7715 newp = cStartNew + (p - cStart)*8 + r; 7716 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7717 } 7718 for (r = 0; r < 12; ++r) { 7719 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 7720 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7721 } 7722 for (r = 0; r < 6; ++r) { 7723 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 7724 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7725 } 7726 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 7727 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7728 } else if ((p >= cMax) && (p < cEnd)) { 7729 /* Hybrid cells add new cells, faces, and edges */ 7730 for (r = 0; r < 4; ++r) { 7731 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7732 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7733 } 7734 for (r = 0; r < 4; ++r) { 7735 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 7736 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7737 } 7738 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 7739 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7740 } 7741 break; 7742 default: 7743 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7744 } 7745 } 7746 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 7747 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 7748 } 7749 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 7750 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 7751 if (0) { 7752 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 7753 } 7754 } 7755 PetscFunctionReturn(0); 7756 } 7757 7758 /* This will only work for interpolated meshes */ 7759 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 7760 { 7761 DM rdm; 7762 PetscInt *depthSize; 7763 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 7764 PetscErrorCode ierr; 7765 7766 PetscFunctionBegin; 7767 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 7768 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 7769 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 7770 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 7771 /* Calculate number of new points of each depth */ 7772 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 7773 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 7774 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 7775 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 7776 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 7777 /* Step 1: Set chart */ 7778 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 7779 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 7780 /* Step 2: Set cone/support sizes */ 7781 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 7782 /* Step 3: Setup refined DM */ 7783 ierr = DMSetUp(rdm);CHKERRQ(ierr); 7784 /* Step 4: Set cones and supports */ 7785 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 7786 /* Step 5: Stratify */ 7787 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 7788 /* Step 6: Create pointSF */ 7789 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 7790 /* Step 7: Set coordinates for vertices */ 7791 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 7792 /* Step 8: Create labels */ 7793 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 7794 ierr = PetscFree(depthSize);CHKERRQ(ierr); 7795 7796 *dmRefined = rdm; 7797 PetscFunctionReturn(0); 7798 } 7799 7800 /*@ 7801 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 7802 7803 Input Parameter: 7804 . dm - The coarse DM 7805 7806 Output Parameter: 7807 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 7808 7809 Level: developer 7810 7811 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 7812 @*/ 7813 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 7814 { 7815 CellRefiner cellRefiner; 7816 PetscInt *depthSize, *fpoints; 7817 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7818 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 7819 PetscErrorCode ierr; 7820 7821 PetscFunctionBegin; 7822 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 7823 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 7824 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7825 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 7826 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 7827 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 7828 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7829 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 7830 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 7831 switch (cellRefiner) { 7832 case REFINER_SIMPLEX_1D: 7833 case REFINER_SIMPLEX_2D: 7834 case REFINER_HYBRID_SIMPLEX_2D: 7835 case REFINER_HEX_2D: 7836 case REFINER_HYBRID_HEX_2D: 7837 case REFINER_SIMPLEX_3D: 7838 case REFINER_HYBRID_SIMPLEX_3D: 7839 case REFINER_HEX_3D: 7840 case REFINER_HYBRID_HEX_3D: 7841 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 7842 break; 7843 default: 7844 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 7845 } 7846 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 7847 ierr = PetscFree(depthSize);CHKERRQ(ierr); 7848 PetscFunctionReturn(0); 7849 } 7850 7851 /*@ 7852 DMPlexSetRefinementUniform - Set the flag for uniform refinement 7853 7854 Input Parameters: 7855 + dm - The DM 7856 - refinementUniform - The flag for uniform refinement 7857 7858 Level: developer 7859 7860 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 7861 @*/ 7862 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 7863 { 7864 DM_Plex *mesh = (DM_Plex*) dm->data; 7865 7866 PetscFunctionBegin; 7867 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7868 mesh->refinementUniform = refinementUniform; 7869 PetscFunctionReturn(0); 7870 } 7871 7872 /*@ 7873 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 7874 7875 Input Parameter: 7876 . dm - The DM 7877 7878 Output Parameter: 7879 . refinementUniform - The flag for uniform refinement 7880 7881 Level: developer 7882 7883 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 7884 @*/ 7885 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 7886 { 7887 DM_Plex *mesh = (DM_Plex*) dm->data; 7888 7889 PetscFunctionBegin; 7890 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7891 PetscValidPointer(refinementUniform, 2); 7892 *refinementUniform = mesh->refinementUniform; 7893 PetscFunctionReturn(0); 7894 } 7895 7896 /*@ 7897 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 7898 7899 Input Parameters: 7900 + dm - The DM 7901 - refinementLimit - The maximum cell volume in the refined mesh 7902 7903 Level: developer 7904 7905 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 7906 @*/ 7907 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 7908 { 7909 DM_Plex *mesh = (DM_Plex*) dm->data; 7910 7911 PetscFunctionBegin; 7912 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7913 mesh->refinementLimit = refinementLimit; 7914 PetscFunctionReturn(0); 7915 } 7916 7917 /*@ 7918 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 7919 7920 Input Parameter: 7921 . dm - The DM 7922 7923 Output Parameter: 7924 . refinementLimit - The maximum cell volume in the refined mesh 7925 7926 Level: developer 7927 7928 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 7929 @*/ 7930 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 7931 { 7932 DM_Plex *mesh = (DM_Plex*) dm->data; 7933 7934 PetscFunctionBegin; 7935 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7936 PetscValidPointer(refinementLimit, 2); 7937 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 7938 *refinementLimit = mesh->refinementLimit; 7939 PetscFunctionReturn(0); 7940 } 7941 7942 /*@ 7943 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 7944 7945 Input Parameters: 7946 + dm - The DM 7947 - refinementFunc - Function giving the maximum cell volume in the refined mesh 7948 7949 Note: The calling sequence is refinementFunc(coords, limit) 7950 $ coords - Coordinates of the current point, usually a cell centroid 7951 $ limit - The maximum cell volume for a cell containing this point 7952 7953 Level: developer 7954 7955 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 7956 @*/ 7957 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 7958 { 7959 DM_Plex *mesh = (DM_Plex*) dm->data; 7960 7961 PetscFunctionBegin; 7962 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7963 mesh->refinementFunc = refinementFunc; 7964 PetscFunctionReturn(0); 7965 } 7966 7967 /*@ 7968 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 7969 7970 Input Parameter: 7971 . dm - The DM 7972 7973 Output Parameter: 7974 . refinementFunc - Function giving the maximum cell volume in the refined mesh 7975 7976 Note: The calling sequence is refinementFunc(coords, limit) 7977 $ coords - Coordinates of the current point, usually a cell centroid 7978 $ limit - The maximum cell volume for a cell containing this point 7979 7980 Level: developer 7981 7982 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 7983 @*/ 7984 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 7985 { 7986 DM_Plex *mesh = (DM_Plex*) dm->data; 7987 7988 PetscFunctionBegin; 7989 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7990 PetscValidPointer(refinementFunc, 2); 7991 *refinementFunc = mesh->refinementFunc; 7992 PetscFunctionReturn(0); 7993 } 7994 7995 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 7996 { 7997 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 7998 PetscErrorCode ierr; 7999 8000 PetscFunctionBegin; 8001 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8002 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8003 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 8004 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 8005 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 8006 switch (dim) { 8007 case 1: 8008 switch (coneSize) { 8009 case 2: 8010 *cellRefiner = REFINER_SIMPLEX_1D; 8011 break; 8012 default: 8013 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8014 } 8015 break; 8016 case 2: 8017 switch (coneSize) { 8018 case 3: 8019 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 8020 else *cellRefiner = REFINER_SIMPLEX_2D; 8021 break; 8022 case 4: 8023 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 8024 else *cellRefiner = REFINER_HEX_2D; 8025 break; 8026 default: 8027 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8028 } 8029 break; 8030 case 3: 8031 switch (coneSize) { 8032 case 4: 8033 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 8034 else *cellRefiner = REFINER_SIMPLEX_3D; 8035 break; 8036 case 6: 8037 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 8038 else *cellRefiner = REFINER_HEX_3D; 8039 break; 8040 default: 8041 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8042 } 8043 break; 8044 default: 8045 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 8046 } 8047 PetscFunctionReturn(0); 8048 } 8049