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] = -2; 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] = 0; 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] = -2; 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] = 0; 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 if (r==1 || r==2) { 1919 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1920 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1921 } else { 1922 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1923 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1924 } 1925 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1926 #if 1 1927 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1928 for (p = 0; p < 2; ++p) { 1929 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); 1930 } 1931 #endif 1932 supportNew[0] = (c - cStart)*4 + r; 1933 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1934 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1935 #if 1 1936 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1937 for (p = 0; p < 2; ++p) { 1938 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); 1939 } 1940 #endif 1941 } 1942 } 1943 /* Old vertices have identical supports */ 1944 for (v = vStart; v < vEnd; ++v) { 1945 const PetscInt newp = vStartNew + (v - vStart); 1946 const PetscInt *support, *cone; 1947 PetscInt size, s; 1948 1949 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1950 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1951 for (s = 0; s < size; ++s) { 1952 PetscInt r = 0; 1953 1954 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1955 if (cone[1] == v) r = 1; 1956 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1957 } 1958 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1959 #if 1 1960 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1961 for (p = 0; p < size; ++p) { 1962 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); 1963 } 1964 #endif 1965 } 1966 /* Face vertices have 2 + cells supports */ 1967 for (f = fStart; f < fEnd; ++f) { 1968 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1969 const PetscInt *cone, *support; 1970 PetscInt size, s; 1971 1972 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1973 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1974 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1975 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1976 for (s = 0; s < size; ++s) { 1977 PetscInt r = 0; 1978 1979 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1980 if (cone[1] == f) r = 1; 1981 else if (cone[2] == f) r = 2; 1982 else if (cone[3] == f) r = 3; 1983 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1984 } 1985 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1986 #if 1 1987 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1988 for (p = 0; p < 2+size; ++p) { 1989 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); 1990 } 1991 #endif 1992 } 1993 /* Cell vertices have 4 supports */ 1994 for (c = cStart; c < cEnd; ++c) { 1995 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1996 PetscInt supportNew[4]; 1997 1998 for (r = 0; r < 4; ++r) { 1999 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2000 } 2001 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2002 } 2003 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2004 break; 2005 case REFINER_HYBRID_SIMPLEX_2D: 2006 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2007 cMax = PetscMin(cEnd, cMax); 2008 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2009 fMax = PetscMin(fEnd, fMax); 2010 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2011 /* Interior cells have 3 faces */ 2012 for (c = cStart; c < cMax; ++c) { 2013 const PetscInt newp = cStartNew + (c - cStart)*4; 2014 const PetscInt *cone, *ornt; 2015 PetscInt coneNew[3], orntNew[3]; 2016 2017 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2018 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2019 /* A triangle */ 2020 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2021 orntNew[0] = ornt[0]; 2022 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2023 orntNew[1] = -2; 2024 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2025 orntNew[2] = ornt[2]; 2026 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2027 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2028 #if 1 2029 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); 2030 for (p = 0; p < 3; ++p) { 2031 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); 2032 } 2033 #endif 2034 /* B triangle */ 2035 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2036 orntNew[0] = ornt[0]; 2037 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2038 orntNew[1] = ornt[1]; 2039 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2040 orntNew[2] = -2; 2041 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2042 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2043 #if 1 2044 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); 2045 for (p = 0; p < 3; ++p) { 2046 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); 2047 } 2048 #endif 2049 /* C triangle */ 2050 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2051 orntNew[0] = -2; 2052 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2053 orntNew[1] = ornt[1]; 2054 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2055 orntNew[2] = ornt[2]; 2056 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2057 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2058 #if 1 2059 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); 2060 for (p = 0; p < 3; ++p) { 2061 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); 2062 } 2063 #endif 2064 /* D triangle */ 2065 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2066 orntNew[0] = 0; 2067 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2068 orntNew[1] = 0; 2069 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2070 orntNew[2] = 0; 2071 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2072 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2073 #if 1 2074 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); 2075 for (p = 0; p < 3; ++p) { 2076 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); 2077 } 2078 #endif 2079 } 2080 /* 2081 2----3----3 2082 | | 2083 | B | 2084 | | 2085 0----4--- 1 2086 | | 2087 | A | 2088 | | 2089 0----2----1 2090 */ 2091 /* Hybrid cells have 4 faces */ 2092 for (c = cMax; c < cEnd; ++c) { 2093 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2094 const PetscInt *cone, *ornt; 2095 PetscInt coneNew[4], orntNew[4], r; 2096 2097 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2098 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2099 r = (ornt[0] < 0 ? 1 : 0); 2100 /* A quad */ 2101 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2102 orntNew[0] = ornt[0]; 2103 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2104 orntNew[1] = ornt[1]; 2105 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2106 orntNew[2+r] = 0; 2107 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2108 orntNew[3-r] = 0; 2109 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2110 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2111 #if 1 2112 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); 2113 for (p = 0; p < 4; ++p) { 2114 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); 2115 } 2116 #endif 2117 /* B quad */ 2118 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2119 orntNew[0] = ornt[0]; 2120 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2121 orntNew[1] = ornt[1]; 2122 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2123 orntNew[2+r] = 0; 2124 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2125 orntNew[3-r] = 0; 2126 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2127 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2128 #if 1 2129 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); 2130 for (p = 0; p < 4; ++p) { 2131 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); 2132 } 2133 #endif 2134 } 2135 /* Interior split faces have 2 vertices and the same cells as the parent */ 2136 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2137 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2138 for (f = fStart; f < fMax; ++f) { 2139 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2140 2141 for (r = 0; r < 2; ++r) { 2142 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2143 const PetscInt *cone, *ornt, *support; 2144 PetscInt coneNew[2], coneSize, c, supportSize, s; 2145 2146 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2147 coneNew[0] = vStartNew + (cone[0] - vStart); 2148 coneNew[1] = vStartNew + (cone[1] - vStart); 2149 coneNew[(r+1)%2] = newv; 2150 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2151 #if 1 2152 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2153 for (p = 0; p < 2; ++p) { 2154 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); 2155 } 2156 #endif 2157 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2158 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2159 for (s = 0; s < supportSize; ++s) { 2160 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2161 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2162 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2163 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2164 if (support[s] >= cMax) { 2165 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2166 } else { 2167 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2168 } 2169 } 2170 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2171 #if 1 2172 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2173 for (p = 0; p < supportSize; ++p) { 2174 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); 2175 } 2176 #endif 2177 } 2178 } 2179 /* Interior cell faces have 2 vertices and 2 cells */ 2180 for (c = cStart; c < cMax; ++c) { 2181 const PetscInt *cone; 2182 2183 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2184 for (r = 0; r < 3; ++r) { 2185 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 2186 PetscInt coneNew[2]; 2187 PetscInt supportNew[2]; 2188 2189 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2190 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 2191 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2192 #if 1 2193 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2194 for (p = 0; p < 2; ++p) { 2195 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); 2196 } 2197 #endif 2198 supportNew[0] = (c - cStart)*4 + (r+1)%3; 2199 supportNew[1] = (c - cStart)*4 + 3; 2200 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2201 #if 1 2202 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2203 for (p = 0; p < 2; ++p) { 2204 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); 2205 } 2206 #endif 2207 } 2208 } 2209 /* Interior hybrid faces have 2 vertices and the same cells */ 2210 for (f = fMax; f < fEnd; ++f) { 2211 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 2212 const PetscInt *cone, *ornt; 2213 const PetscInt *support; 2214 PetscInt coneNew[2]; 2215 PetscInt supportNew[2]; 2216 PetscInt size, s, r; 2217 2218 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2219 coneNew[0] = vStartNew + (cone[0] - vStart); 2220 coneNew[1] = vStartNew + (cone[1] - vStart); 2221 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2222 #if 1 2223 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2224 for (p = 0; p < 2; ++p) { 2225 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); 2226 } 2227 #endif 2228 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2229 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2230 for (s = 0; s < size; ++s) { 2231 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2232 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2233 for (r = 0; r < 2; ++r) { 2234 if (cone[r+2] == f) break; 2235 } 2236 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 2237 } 2238 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2239 #if 1 2240 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2241 for (p = 0; p < size; ++p) { 2242 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); 2243 } 2244 #endif 2245 } 2246 /* Cell hybrid faces have 2 vertices and 2 cells */ 2247 for (c = cMax; c < cEnd; ++c) { 2248 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2249 const PetscInt *cone; 2250 PetscInt coneNew[2]; 2251 PetscInt supportNew[2]; 2252 2253 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2254 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2255 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2256 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2257 #if 1 2258 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2259 for (p = 0; p < 2; ++p) { 2260 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); 2261 } 2262 #endif 2263 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2264 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2265 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2266 #if 1 2267 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2268 for (p = 0; p < 2; ++p) { 2269 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); 2270 } 2271 #endif 2272 } 2273 /* Old vertices have identical supports */ 2274 for (v = vStart; v < vEnd; ++v) { 2275 const PetscInt newp = vStartNew + (v - vStart); 2276 const PetscInt *support, *cone; 2277 PetscInt size, s; 2278 2279 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2280 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2281 for (s = 0; s < size; ++s) { 2282 if (support[s] >= fMax) { 2283 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 2284 } else { 2285 PetscInt r = 0; 2286 2287 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2288 if (cone[1] == v) r = 1; 2289 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2290 } 2291 } 2292 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2293 #if 1 2294 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2295 for (p = 0; p < size; ++p) { 2296 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); 2297 } 2298 #endif 2299 } 2300 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 2301 for (f = fStart; f < fMax; ++f) { 2302 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2303 const PetscInt *cone, *support; 2304 PetscInt size, newSize = 2, s; 2305 2306 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2307 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2308 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2309 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2310 for (s = 0; s < size; ++s) { 2311 PetscInt r = 0; 2312 2313 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2314 if (support[s] >= cMax) { 2315 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 2316 2317 newSize += 1; 2318 } else { 2319 if (cone[1] == f) r = 1; 2320 else if (cone[2] == f) r = 2; 2321 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 2322 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 2323 2324 newSize += 2; 2325 } 2326 } 2327 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2328 #if 1 2329 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2330 for (p = 0; p < newSize; ++p) { 2331 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); 2332 } 2333 #endif 2334 } 2335 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2336 break; 2337 case REFINER_HYBRID_HEX_2D: 2338 /* Hybrid Hex 2D */ 2339 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2340 cMax = PetscMin(cEnd, cMax); 2341 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2342 fMax = PetscMin(fEnd, fMax); 2343 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2344 /* Interior cells have 4 faces */ 2345 for (c = cStart; c < cMax; ++c) { 2346 const PetscInt newp = cStartNew + (c - cStart)*4; 2347 const PetscInt *cone, *ornt; 2348 PetscInt coneNew[4], orntNew[4]; 2349 2350 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2351 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2352 /* A quad */ 2353 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2354 orntNew[0] = ornt[0]; 2355 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 2356 orntNew[1] = 0; 2357 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2358 orntNew[2] = -2; 2359 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2360 orntNew[3] = ornt[3]; 2361 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2362 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2363 #if 1 2364 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); 2365 for (p = 0; p < 4; ++p) { 2366 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); 2367 } 2368 #endif 2369 /* B quad */ 2370 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2371 orntNew[0] = ornt[0]; 2372 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2373 orntNew[1] = ornt[1]; 2374 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2375 orntNew[2] = 0; 2376 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 2377 orntNew[3] = -2; 2378 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2379 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2380 #if 1 2381 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); 2382 for (p = 0; p < 4; ++p) { 2383 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); 2384 } 2385 #endif 2386 /* C quad */ 2387 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2388 orntNew[0] = -2; 2389 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2390 orntNew[1] = ornt[1]; 2391 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2392 orntNew[2] = ornt[2]; 2393 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2394 orntNew[3] = 0; 2395 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2396 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2397 #if 1 2398 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); 2399 for (p = 0; p < 4; ++p) { 2400 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); 2401 } 2402 #endif 2403 /* D quad */ 2404 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2405 orntNew[0] = 0; 2406 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2407 orntNew[1] = -2; 2408 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2409 orntNew[2] = ornt[2]; 2410 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2411 orntNew[3] = ornt[3]; 2412 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2413 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2414 #if 1 2415 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); 2416 for (p = 0; p < 4; ++p) { 2417 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); 2418 } 2419 #endif 2420 } 2421 /* 2422 2----3----3 2423 | | 2424 | B | 2425 | | 2426 0----4--- 1 2427 | | 2428 | A | 2429 | | 2430 0----2----1 2431 */ 2432 /* Hybrid cells have 4 faces */ 2433 for (c = cMax; c < cEnd; ++c) { 2434 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2435 const PetscInt *cone, *ornt; 2436 PetscInt coneNew[4], orntNew[4]; 2437 2438 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2439 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2440 /* A quad */ 2441 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2442 orntNew[0] = ornt[0]; 2443 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2444 orntNew[1] = ornt[1]; 2445 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 2446 orntNew[2] = 0; 2447 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2448 orntNew[3] = 0; 2449 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2450 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2451 #if 1 2452 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); 2453 for (p = 0; p < 4; ++p) { 2454 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); 2455 } 2456 #endif 2457 /* B quad */ 2458 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2459 orntNew[0] = ornt[0]; 2460 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2461 orntNew[1] = ornt[1]; 2462 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2463 orntNew[2] = 0; 2464 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 2465 orntNew[3] = 0; 2466 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2467 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2468 #if 1 2469 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); 2470 for (p = 0; p < 4; ++p) { 2471 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); 2472 } 2473 #endif 2474 } 2475 /* Interior split faces have 2 vertices and the same cells as the parent */ 2476 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2477 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2478 for (f = fStart; f < fMax; ++f) { 2479 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2480 2481 for (r = 0; r < 2; ++r) { 2482 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2483 const PetscInt *cone, *ornt, *support; 2484 PetscInt coneNew[2], coneSize, c, supportSize, s; 2485 2486 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2487 coneNew[0] = vStartNew + (cone[0] - vStart); 2488 coneNew[1] = vStartNew + (cone[1] - vStart); 2489 coneNew[(r+1)%2] = newv; 2490 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2491 #if 1 2492 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2493 for (p = 0; p < 2; ++p) { 2494 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); 2495 } 2496 #endif 2497 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2498 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2499 for (s = 0; s < supportSize; ++s) { 2500 if (support[s] >= cMax) { 2501 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2502 } else { 2503 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2504 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2505 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2506 for (c = 0; c < coneSize; ++c) { 2507 if (cone[c] == f) break; 2508 } 2509 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2510 } 2511 } 2512 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2513 #if 1 2514 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2515 for (p = 0; p < supportSize; ++p) { 2516 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); 2517 } 2518 #endif 2519 } 2520 } 2521 /* Interior cell faces have 2 vertices and 2 cells */ 2522 for (c = cStart; c < cMax; ++c) { 2523 const PetscInt *cone; 2524 2525 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2526 for (r = 0; r < 4; ++r) { 2527 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2528 PetscInt coneNew[2], supportNew[2]; 2529 2530 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2531 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2532 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2533 #if 1 2534 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2535 for (p = 0; p < 2; ++p) { 2536 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); 2537 } 2538 #endif 2539 supportNew[0] = (c - cStart)*4 + r; 2540 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2541 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2542 #if 1 2543 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2544 for (p = 0; p < 2; ++p) { 2545 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); 2546 } 2547 #endif 2548 } 2549 } 2550 /* Hybrid faces have 2 vertices and the same cells */ 2551 for (f = fMax; f < fEnd; ++f) { 2552 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 2553 const PetscInt *cone, *support; 2554 PetscInt coneNew[2], supportNew[2]; 2555 PetscInt size, s, r; 2556 2557 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2558 coneNew[0] = vStartNew + (cone[0] - vStart); 2559 coneNew[1] = vStartNew + (cone[1] - vStart); 2560 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2561 #if 1 2562 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2563 for (p = 0; p < 2; ++p) { 2564 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); 2565 } 2566 #endif 2567 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2568 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2569 for (s = 0; s < size; ++s) { 2570 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2571 for (r = 0; r < 2; ++r) { 2572 if (cone[r+2] == f) break; 2573 } 2574 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2575 } 2576 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2577 #if 1 2578 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2579 for (p = 0; p < size; ++p) { 2580 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); 2581 } 2582 #endif 2583 } 2584 /* Cell hybrid faces have 2 vertices and 2 cells */ 2585 for (c = cMax; c < cEnd; ++c) { 2586 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2587 const PetscInt *cone; 2588 PetscInt coneNew[2], supportNew[2]; 2589 2590 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2591 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2592 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2593 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2594 #if 1 2595 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2596 for (p = 0; p < 2; ++p) { 2597 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); 2598 } 2599 #endif 2600 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2601 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2602 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2603 #if 1 2604 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2605 for (p = 0; p < 2; ++p) { 2606 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); 2607 } 2608 #endif 2609 } 2610 /* Old vertices have identical supports */ 2611 for (v = vStart; v < vEnd; ++v) { 2612 const PetscInt newp = vStartNew + (v - vStart); 2613 const PetscInt *support, *cone; 2614 PetscInt size, s; 2615 2616 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2617 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2618 for (s = 0; s < size; ++s) { 2619 if (support[s] >= fMax) { 2620 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2621 } else { 2622 PetscInt r = 0; 2623 2624 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2625 if (cone[1] == v) r = 1; 2626 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2627 } 2628 } 2629 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2630 #if 1 2631 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2632 for (p = 0; p < size; ++p) { 2633 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); 2634 } 2635 #endif 2636 } 2637 /* Face vertices have 2 + cells supports */ 2638 for (f = fStart; f < fMax; ++f) { 2639 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2640 const PetscInt *cone, *support; 2641 PetscInt size, s; 2642 2643 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2644 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2645 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2646 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2647 for (s = 0; s < size; ++s) { 2648 PetscInt r = 0; 2649 2650 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2651 if (support[s] >= cMax) { 2652 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2653 } else { 2654 if (cone[1] == f) r = 1; 2655 else if (cone[2] == f) r = 2; 2656 else if (cone[3] == f) r = 3; 2657 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2658 } 2659 } 2660 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2661 #if 1 2662 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2663 for (p = 0; p < 2+size; ++p) { 2664 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); 2665 } 2666 #endif 2667 } 2668 /* Cell vertices have 4 supports */ 2669 for (c = cStart; c < cMax; ++c) { 2670 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2671 PetscInt supportNew[4]; 2672 2673 for (r = 0; r < 4; ++r) { 2674 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2675 } 2676 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2677 } 2678 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2679 break; 2680 case REFINER_SIMPLEX_3D: 2681 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2682 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2683 for (c = cStart; c < cEnd; ++c) { 2684 const PetscInt newp = cStartNew + (c - cStart)*8; 2685 const PetscInt *cone, *ornt; 2686 PetscInt coneNew[4], orntNew[4]; 2687 2688 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2689 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2690 /* A tetrahedron: {0, a, c, d} */ 2691 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2692 orntNew[0] = ornt[0]; 2693 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2694 orntNew[1] = ornt[1]; 2695 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2696 orntNew[2] = ornt[2]; 2697 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2698 orntNew[3] = 0; 2699 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2700 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2701 #if 1 2702 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); 2703 for (p = 0; p < 4; ++p) { 2704 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); 2705 } 2706 #endif 2707 /* B tetrahedron: {a, 1, b, e} */ 2708 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2709 orntNew[0] = ornt[0]; 2710 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2711 orntNew[1] = ornt[1]; 2712 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2713 orntNew[2] = 0; 2714 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2715 orntNew[3] = ornt[3]; 2716 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2717 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2718 #if 1 2719 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); 2720 for (p = 0; p < 4; ++p) { 2721 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); 2722 } 2723 #endif 2724 /* C tetrahedron: {c, b, 2, f} */ 2725 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2726 orntNew[0] = ornt[0]; 2727 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2728 orntNew[1] = 0; 2729 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2730 orntNew[2] = ornt[2]; 2731 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2732 orntNew[3] = ornt[3]; 2733 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2734 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2735 #if 1 2736 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); 2737 for (p = 0; p < 4; ++p) { 2738 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); 2739 } 2740 #endif 2741 /* D tetrahedron: {d, e, f, 3} */ 2742 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2743 orntNew[0] = 0; 2744 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2745 orntNew[1] = ornt[1]; 2746 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2747 orntNew[2] = ornt[2]; 2748 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2749 orntNew[3] = ornt[3]; 2750 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2751 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2752 #if 1 2753 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); 2754 for (p = 0; p < 4; ++p) { 2755 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); 2756 } 2757 #endif 2758 /* A' tetrahedron: {c, d, a, f} */ 2759 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2760 orntNew[0] = -3; 2761 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2762 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 2763 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2764 orntNew[2] = 0; 2765 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2766 orntNew[3] = 2; 2767 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2768 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2769 #if 1 2770 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); 2771 for (p = 0; p < 4; ++p) { 2772 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); 2773 } 2774 #endif 2775 /* B' tetrahedron: {e, b, a, f} */ 2776 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2777 orntNew[0] = -2; 2778 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 2779 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 2780 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2781 orntNew[2] = 0; 2782 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2783 orntNew[3] = 0; 2784 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2785 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2786 #if 1 2787 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); 2788 for (p = 0; p < 4; ++p) { 2789 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); 2790 } 2791 #endif 2792 /* C' tetrahedron: {f, a, c, b} */ 2793 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2794 orntNew[0] = -2; 2795 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2796 orntNew[1] = -2; 2797 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2798 orntNew[2] = -1; 2799 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 2800 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 2801 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2802 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2803 #if 1 2804 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); 2805 for (p = 0; p < 4; ++p) { 2806 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); 2807 } 2808 #endif 2809 /* D' tetrahedron: {f, a, e, d} */ 2810 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2811 orntNew[0] = -2; 2812 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2813 orntNew[1] = -1; 2814 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2815 orntNew[2] = -2; 2816 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 2817 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 2818 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2819 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2820 #if 1 2821 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); 2822 for (p = 0; p < 4; ++p) { 2823 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); 2824 } 2825 #endif 2826 } 2827 /* Split faces have 3 edges and the same cells as the parent */ 2828 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2829 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2830 for (f = fStart; f < fEnd; ++f) { 2831 const PetscInt newp = fStartNew + (f - fStart)*4; 2832 const PetscInt *cone, *ornt, *support; 2833 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2834 2835 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2836 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2837 /* A triangle */ 2838 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2839 orntNew[0] = ornt[0]; 2840 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2841 orntNew[1] = -2; 2842 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2843 orntNew[2] = ornt[2]; 2844 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2845 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2846 #if 1 2847 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); 2848 for (p = 0; p < 3; ++p) { 2849 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); 2850 } 2851 #endif 2852 /* B triangle */ 2853 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2854 orntNew[0] = ornt[0]; 2855 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2856 orntNew[1] = ornt[1]; 2857 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2858 orntNew[2] = -2; 2859 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2860 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2861 #if 1 2862 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); 2863 for (p = 0; p < 3; ++p) { 2864 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); 2865 } 2866 #endif 2867 /* C triangle */ 2868 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2869 orntNew[0] = -2; 2870 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2871 orntNew[1] = ornt[1]; 2872 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2873 orntNew[2] = ornt[2]; 2874 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2875 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2876 #if 1 2877 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); 2878 for (p = 0; p < 3; ++p) { 2879 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); 2880 } 2881 #endif 2882 /* D triangle */ 2883 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2884 orntNew[0] = 0; 2885 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2886 orntNew[1] = 0; 2887 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2888 orntNew[2] = 0; 2889 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2890 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2891 #if 1 2892 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); 2893 for (p = 0; p < 3; ++p) { 2894 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); 2895 } 2896 #endif 2897 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2898 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2899 for (r = 0; r < 4; ++r) { 2900 for (s = 0; s < supportSize; ++s) { 2901 PetscInt subf; 2902 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2903 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2904 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2905 for (c = 0; c < coneSize; ++c) { 2906 if (cone[c] == f) break; 2907 } 2908 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2909 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2910 } 2911 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2912 #if 1 2913 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); 2914 for (p = 0; p < supportSize; ++p) { 2915 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); 2916 } 2917 #endif 2918 } 2919 } 2920 /* Interior faces have 3 edges and 2 cells */ 2921 for (c = cStart; c < cEnd; ++c) { 2922 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2923 const PetscInt *cone, *ornt; 2924 PetscInt coneNew[3], orntNew[3]; 2925 PetscInt supportNew[2]; 2926 2927 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2928 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2929 /* Face A: {c, a, d} */ 2930 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 2931 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2932 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 2933 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2934 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 2935 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2936 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2937 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2938 #if 1 2939 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2940 for (p = 0; p < 3; ++p) { 2941 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); 2942 } 2943 #endif 2944 supportNew[0] = (c - cStart)*8 + 0; 2945 supportNew[1] = (c - cStart)*8 + 0+4; 2946 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2947 #if 1 2948 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2949 for (p = 0; p < 2; ++p) { 2950 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); 2951 } 2952 #endif 2953 ++newp; 2954 /* Face B: {a, b, e} */ 2955 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 2956 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2957 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 2958 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2959 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 2960 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2961 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2962 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2963 #if 1 2964 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2965 for (p = 0; p < 3; ++p) { 2966 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); 2967 } 2968 #endif 2969 supportNew[0] = (c - cStart)*8 + 1; 2970 supportNew[1] = (c - cStart)*8 + 1+4; 2971 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2972 #if 1 2973 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2974 for (p = 0; p < 2; ++p) { 2975 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); 2976 } 2977 #endif 2978 ++newp; 2979 /* Face C: {c, f, b} */ 2980 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 2981 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2982 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 2983 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2984 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 2985 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2986 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2987 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2988 #if 1 2989 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2990 for (p = 0; p < 3; ++p) { 2991 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); 2992 } 2993 #endif 2994 supportNew[0] = (c - cStart)*8 + 2; 2995 supportNew[1] = (c - cStart)*8 + 2+4; 2996 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2997 #if 1 2998 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2999 for (p = 0; p < 2; ++p) { 3000 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); 3001 } 3002 #endif 3003 ++newp; 3004 /* Face D: {d, e, f} */ 3005 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3006 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3007 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3008 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3009 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3010 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3011 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3012 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3013 #if 1 3014 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3015 for (p = 0; p < 3; ++p) { 3016 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); 3017 } 3018 #endif 3019 supportNew[0] = (c - cStart)*8 + 3; 3020 supportNew[1] = (c - cStart)*8 + 3+4; 3021 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3022 #if 1 3023 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3024 for (p = 0; p < 2; ++p) { 3025 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); 3026 } 3027 #endif 3028 ++newp; 3029 /* Face E: {d, f, a} */ 3030 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3031 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3032 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3033 orntNew[1] = -2; 3034 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3035 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3036 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3037 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3038 #if 1 3039 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3040 for (p = 0; p < 3; ++p) { 3041 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); 3042 } 3043 #endif 3044 supportNew[0] = (c - cStart)*8 + 0+4; 3045 supportNew[1] = (c - cStart)*8 + 3+4; 3046 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3047 #if 1 3048 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3049 for (p = 0; p < 2; ++p) { 3050 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); 3051 } 3052 #endif 3053 ++newp; 3054 /* Face F: {c, a, f} */ 3055 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3056 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3057 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3058 orntNew[1] = 0; 3059 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3060 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3061 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3062 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3063 #if 1 3064 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3065 for (p = 0; p < 3; ++p) { 3066 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); 3067 } 3068 #endif 3069 supportNew[0] = (c - cStart)*8 + 0+4; 3070 supportNew[1] = (c - cStart)*8 + 2+4; 3071 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3072 #if 1 3073 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3074 for (p = 0; p < 2; ++p) { 3075 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); 3076 } 3077 #endif 3078 ++newp; 3079 /* Face G: {e, a, f} */ 3080 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3081 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3082 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3083 orntNew[1] = 0; 3084 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3085 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3086 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3087 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3088 #if 1 3089 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3090 for (p = 0; p < 3; ++p) { 3091 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); 3092 } 3093 #endif 3094 supportNew[0] = (c - cStart)*8 + 1+4; 3095 supportNew[1] = (c - cStart)*8 + 3+4; 3096 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3097 #if 1 3098 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3099 for (p = 0; p < 2; ++p) { 3100 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); 3101 } 3102 #endif 3103 ++newp; 3104 /* Face H: {a, b, f} */ 3105 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3106 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3107 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3108 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3109 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3110 orntNew[2] = -2; 3111 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3112 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3113 #if 1 3114 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3115 for (p = 0; p < 3; ++p) { 3116 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); 3117 } 3118 #endif 3119 supportNew[0] = (c - cStart)*8 + 1+4; 3120 supportNew[1] = (c - cStart)*8 + 2+4; 3121 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3122 #if 1 3123 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3124 for (p = 0; p < 2; ++p) { 3125 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); 3126 } 3127 #endif 3128 ++newp; 3129 } 3130 /* Split Edges have 2 vertices and the same faces as the parent */ 3131 for (e = eStart; e < eEnd; ++e) { 3132 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3133 3134 for (r = 0; r < 2; ++r) { 3135 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3136 const PetscInt *cone, *ornt, *support; 3137 PetscInt coneNew[2], coneSize, c, supportSize, s; 3138 3139 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3140 coneNew[0] = vStartNew + (cone[0] - vStart); 3141 coneNew[1] = vStartNew + (cone[1] - vStart); 3142 coneNew[(r+1)%2] = newv; 3143 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3144 #if 1 3145 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3146 for (p = 0; p < 2; ++p) { 3147 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); 3148 } 3149 #endif 3150 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3151 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3152 for (s = 0; s < supportSize; ++s) { 3153 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3154 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3155 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3156 for (c = 0; c < coneSize; ++c) { 3157 if (cone[c] == e) break; 3158 } 3159 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3160 } 3161 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3162 #if 1 3163 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3164 for (p = 0; p < supportSize; ++p) { 3165 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); 3166 } 3167 #endif 3168 } 3169 } 3170 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3171 for (f = fStart; f < fEnd; ++f) { 3172 const PetscInt *cone, *ornt, *support; 3173 PetscInt coneSize, supportSize, s; 3174 3175 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3176 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3177 for (r = 0; r < 3; ++r) { 3178 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3179 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3180 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3181 -1, -1, 1, 6, 0, 4, 3182 2, 5, 3, 4, -1, -1, 3183 -1, -1, 3, 6, 2, 7}; 3184 3185 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3186 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3187 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3188 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3189 #if 1 3190 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3191 for (p = 0; p < 2; ++p) { 3192 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); 3193 } 3194 #endif 3195 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3196 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3197 for (s = 0; s < supportSize; ++s) { 3198 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3199 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3200 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3201 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3202 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3203 er = GetTriMidEdgeInverse_Static(ornt[c], r); 3204 if (er == eint[c]) { 3205 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3206 } else { 3207 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3208 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3209 } 3210 } 3211 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3212 #if 1 3213 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3214 for (p = 0; p < intFaces; ++p) { 3215 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); 3216 } 3217 #endif 3218 } 3219 } 3220 /* Interior edges have 2 vertices and 4 faces */ 3221 for (c = cStart; c < cEnd; ++c) { 3222 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3223 const PetscInt *cone, *ornt, *fcone; 3224 PetscInt coneNew[2], supportNew[4], find; 3225 3226 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3227 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3228 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3229 find = GetTriEdge_Static(ornt[0], 0); 3230 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3231 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3232 find = GetTriEdge_Static(ornt[2], 1); 3233 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3234 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3235 #if 1 3236 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3237 for (p = 0; p < 2; ++p) { 3238 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); 3239 } 3240 #endif 3241 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3242 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3243 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3244 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3245 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3246 #if 1 3247 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3248 for (p = 0; p < 4; ++p) { 3249 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); 3250 } 3251 #endif 3252 } 3253 /* Old vertices have identical supports */ 3254 for (v = vStart; v < vEnd; ++v) { 3255 const PetscInt newp = vStartNew + (v - vStart); 3256 const PetscInt *support, *cone; 3257 PetscInt size, s; 3258 3259 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3260 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3261 for (s = 0; s < size; ++s) { 3262 PetscInt r = 0; 3263 3264 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3265 if (cone[1] == v) r = 1; 3266 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3267 } 3268 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3269 #if 1 3270 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3271 for (p = 0; p < size; ++p) { 3272 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); 3273 } 3274 #endif 3275 } 3276 /* Edge vertices have 2 + face*2 + 0/1 supports */ 3277 for (e = eStart; e < eEnd; ++e) { 3278 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3279 const PetscInt *cone, *support; 3280 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 3281 3282 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3283 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3284 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3285 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3286 for (s = 0; s < size; ++s) { 3287 PetscInt r = 0; 3288 3289 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3290 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3291 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3292 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3293 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3294 } 3295 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3296 for (s = 0; s < starSize*2; s += 2) { 3297 const PetscInt *cone, *ornt; 3298 PetscInt e01, e23; 3299 3300 if ((star[s] >= cStart) && (star[s] < cEnd)) { 3301 /* Check edge 0-1 */ 3302 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3303 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3304 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3305 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3306 /* Check edge 2-3 */ 3307 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3308 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3309 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3310 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3311 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 3312 } 3313 } 3314 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3315 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3316 #if 1 3317 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3318 for (p = 0; p < 2+size*2+cellSize; ++p) { 3319 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); 3320 } 3321 #endif 3322 } 3323 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3324 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3325 break; 3326 case REFINER_HYBRID_SIMPLEX_3D: 3327 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 3328 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3329 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3330 for (c = cStart; c < cMax; ++c) { 3331 const PetscInt newp = cStartNew + (c - cStart)*8; 3332 const PetscInt *cone, *ornt; 3333 PetscInt coneNew[4], orntNew[4]; 3334 3335 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3336 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3337 /* A tetrahedron: {0, a, c, d} */ 3338 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3339 orntNew[0] = ornt[0]; 3340 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3341 orntNew[1] = ornt[1]; 3342 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3343 orntNew[2] = ornt[2]; 3344 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3345 orntNew[3] = 0; 3346 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3347 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3348 #if 1 3349 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); 3350 for (p = 0; p < 4; ++p) { 3351 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); 3352 } 3353 #endif 3354 /* B tetrahedron: {a, 1, b, e} */ 3355 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3356 orntNew[0] = ornt[0]; 3357 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3358 orntNew[1] = ornt[1]; 3359 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3360 orntNew[2] = 0; 3361 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3362 orntNew[3] = ornt[3]; 3363 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3364 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3365 #if 1 3366 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); 3367 for (p = 0; p < 4; ++p) { 3368 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); 3369 } 3370 #endif 3371 /* C tetrahedron: {c, b, 2, f} */ 3372 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3373 orntNew[0] = ornt[0]; 3374 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3375 orntNew[1] = 0; 3376 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3377 orntNew[2] = ornt[2]; 3378 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3379 orntNew[3] = ornt[3]; 3380 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3381 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3382 #if 1 3383 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); 3384 for (p = 0; p < 4; ++p) { 3385 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); 3386 } 3387 #endif 3388 /* D tetrahedron: {d, e, f, 3} */ 3389 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3390 orntNew[0] = 0; 3391 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3392 orntNew[1] = ornt[1]; 3393 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3394 orntNew[2] = ornt[2]; 3395 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3396 orntNew[3] = ornt[3]; 3397 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3398 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3399 #if 1 3400 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); 3401 for (p = 0; p < 4; ++p) { 3402 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); 3403 } 3404 #endif 3405 /* A' tetrahedron: {d, a, c, f} */ 3406 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3407 orntNew[0] = -3; 3408 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3409 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3410 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3411 orntNew[2] = 0; 3412 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3413 orntNew[3] = 2; 3414 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3415 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3416 #if 1 3417 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); 3418 for (p = 0; p < 4; ++p) { 3419 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); 3420 } 3421 #endif 3422 /* B' tetrahedron: {e, b, a, f} */ 3423 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3424 orntNew[0] = -3; 3425 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3426 orntNew[1] = 1; 3427 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3428 orntNew[2] = 0; 3429 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 3430 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 3431 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3432 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3433 #if 1 3434 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); 3435 for (p = 0; p < 4; ++p) { 3436 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); 3437 } 3438 #endif 3439 /* C' tetrahedron: {b, f, c, a} */ 3440 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3441 orntNew[0] = -3; 3442 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 3443 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3444 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3445 orntNew[2] = -3; 3446 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3447 orntNew[3] = -2; 3448 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3449 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3450 #if 1 3451 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); 3452 for (p = 0; p < 4; ++p) { 3453 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); 3454 } 3455 #endif 3456 /* D' tetrahedron: {f, e, d, a} */ 3457 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3458 orntNew[0] = -3; 3459 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3460 orntNew[1] = -3; 3461 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 3462 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 3463 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3464 orntNew[3] = -3; 3465 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3466 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3467 #if 1 3468 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); 3469 for (p = 0; p < 4; ++p) { 3470 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); 3471 } 3472 #endif 3473 } 3474 /* Hybrid cells have 5 faces */ 3475 for (c = cMax; c < cEnd; ++c) { 3476 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 3477 const PetscInt *cone, *ornt, *fornt; 3478 PetscInt coneNew[5], orntNew[5], o, of, i; 3479 3480 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3481 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3482 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 3483 o = ornt[0] < 0 ? -1 : 1; 3484 for (r = 0; r < 3; ++r) { 3485 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 3486 orntNew[0] = ornt[0]; 3487 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 3488 orntNew[1] = ornt[1]; 3489 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 3490 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 3491 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 3492 orntNew[i] = 0; 3493 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 3494 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 3495 orntNew[i] = 0; 3496 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 3497 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 3498 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); 3499 orntNew[i] = 0; 3500 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3501 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3502 #if 1 3503 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); 3504 for (p = 0; p < 2; ++p) { 3505 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); 3506 } 3507 for (p = 2; p < 5; ++p) { 3508 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); 3509 } 3510 #endif 3511 } 3512 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 3513 orntNew[0] = 0; 3514 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3515 orntNew[1] = 0; 3516 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3517 orntNew[2] = 0; 3518 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3519 orntNew[3] = 0; 3520 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3521 orntNew[4] = 0; 3522 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3523 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3524 #if 1 3525 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); 3526 for (p = 0; p < 2; ++p) { 3527 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); 3528 } 3529 for (p = 2; p < 5; ++p) { 3530 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); 3531 } 3532 #endif 3533 } 3534 /* Split faces have 3 edges and the same cells as the parent */ 3535 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3536 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3537 for (f = fStart; f < fMax; ++f) { 3538 const PetscInt newp = fStartNew + (f - fStart)*4; 3539 const PetscInt *cone, *ornt, *support; 3540 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3541 3542 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3543 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3544 /* A triangle */ 3545 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3546 orntNew[0] = ornt[0]; 3547 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3548 orntNew[1] = -2; 3549 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3550 orntNew[2] = ornt[2]; 3551 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3552 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3553 #if 1 3554 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); 3555 for (p = 0; p < 3; ++p) { 3556 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); 3557 } 3558 #endif 3559 /* B triangle */ 3560 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3561 orntNew[0] = ornt[0]; 3562 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3563 orntNew[1] = ornt[1]; 3564 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3565 orntNew[2] = -2; 3566 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3567 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3568 #if 1 3569 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); 3570 for (p = 0; p < 3; ++p) { 3571 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); 3572 } 3573 #endif 3574 /* C triangle */ 3575 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3576 orntNew[0] = -2; 3577 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3578 orntNew[1] = ornt[1]; 3579 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3580 orntNew[2] = ornt[2]; 3581 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3582 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3583 #if 1 3584 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); 3585 for (p = 0; p < 3; ++p) { 3586 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); 3587 } 3588 #endif 3589 /* D triangle */ 3590 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3591 orntNew[0] = 0; 3592 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3593 orntNew[1] = 0; 3594 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3595 orntNew[2] = 0; 3596 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3597 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3598 #if 1 3599 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); 3600 for (p = 0; p < 3; ++p) { 3601 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); 3602 } 3603 #endif 3604 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3605 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3606 for (r = 0; r < 4; ++r) { 3607 for (s = 0; s < supportSize; ++s) { 3608 PetscInt subf; 3609 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3610 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3611 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3612 for (c = 0; c < coneSize; ++c) { 3613 if (cone[c] == f) break; 3614 } 3615 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3616 if (support[s] < cMax) { 3617 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3618 } else { 3619 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3620 } 3621 } 3622 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3623 #if 1 3624 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); 3625 for (p = 0; p < supportSize; ++p) { 3626 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); 3627 } 3628 #endif 3629 } 3630 } 3631 /* Interior cell faces have 3 edges and 2 cells */ 3632 for (c = cStart; c < cMax; ++c) { 3633 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3634 const PetscInt *cone, *ornt; 3635 PetscInt coneNew[3], orntNew[3]; 3636 PetscInt supportNew[2]; 3637 3638 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3639 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3640 /* Face A: {c, a, d} */ 3641 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3642 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3643 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3644 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3645 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3646 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3647 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3648 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3649 #if 1 3650 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3651 for (p = 0; p < 3; ++p) { 3652 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); 3653 } 3654 #endif 3655 supportNew[0] = (c - cStart)*8 + 0; 3656 supportNew[1] = (c - cStart)*8 + 0+4; 3657 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3658 #if 1 3659 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3660 for (p = 0; p < 2; ++p) { 3661 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); 3662 } 3663 #endif 3664 ++newp; 3665 /* Face B: {a, b, e} */ 3666 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3667 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3668 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3669 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3670 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3671 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3672 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3673 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3674 #if 1 3675 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); 3676 for (p = 0; p < 3; ++p) { 3677 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); 3678 } 3679 #endif 3680 supportNew[0] = (c - cStart)*8 + 1; 3681 supportNew[1] = (c - cStart)*8 + 1+4; 3682 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3683 #if 1 3684 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3685 for (p = 0; p < 2; ++p) { 3686 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); 3687 } 3688 #endif 3689 ++newp; 3690 /* Face C: {c, f, b} */ 3691 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3692 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3693 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3694 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3695 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3696 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3697 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3698 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3699 #if 1 3700 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3701 for (p = 0; p < 3; ++p) { 3702 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); 3703 } 3704 #endif 3705 supportNew[0] = (c - cStart)*8 + 2; 3706 supportNew[1] = (c - cStart)*8 + 2+4; 3707 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3708 #if 1 3709 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3710 for (p = 0; p < 2; ++p) { 3711 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); 3712 } 3713 #endif 3714 ++newp; 3715 /* Face D: {d, e, f} */ 3716 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3717 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3718 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3719 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3720 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3721 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3722 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3723 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3724 #if 1 3725 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3726 for (p = 0; p < 3; ++p) { 3727 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); 3728 } 3729 #endif 3730 supportNew[0] = (c - cStart)*8 + 3; 3731 supportNew[1] = (c - cStart)*8 + 3+4; 3732 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3733 #if 1 3734 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3735 for (p = 0; p < 2; ++p) { 3736 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); 3737 } 3738 #endif 3739 ++newp; 3740 /* Face E: {d, f, a} */ 3741 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3742 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3743 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3744 orntNew[1] = -2; 3745 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3746 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3747 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3748 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3749 #if 1 3750 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3751 for (p = 0; p < 3; ++p) { 3752 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); 3753 } 3754 #endif 3755 supportNew[0] = (c - cStart)*8 + 0+4; 3756 supportNew[1] = (c - cStart)*8 + 3+4; 3757 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3758 #if 1 3759 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3760 for (p = 0; p < 2; ++p) { 3761 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); 3762 } 3763 #endif 3764 ++newp; 3765 /* Face F: {c, a, f} */ 3766 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3767 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3768 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3769 orntNew[1] = 0; 3770 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3771 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3772 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3773 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3774 #if 1 3775 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3776 for (p = 0; p < 3; ++p) { 3777 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); 3778 } 3779 #endif 3780 supportNew[0] = (c - cStart)*8 + 0+4; 3781 supportNew[1] = (c - cStart)*8 + 2+4; 3782 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3783 #if 1 3784 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3785 for (p = 0; p < 2; ++p) { 3786 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); 3787 } 3788 #endif 3789 ++newp; 3790 /* Face G: {e, a, f} */ 3791 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3792 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3793 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3794 orntNew[1] = 0; 3795 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3796 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3797 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3798 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3799 #if 1 3800 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3801 for (p = 0; p < 3; ++p) { 3802 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); 3803 } 3804 #endif 3805 supportNew[0] = (c - cStart)*8 + 1+4; 3806 supportNew[1] = (c - cStart)*8 + 3+4; 3807 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3808 #if 1 3809 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3810 for (p = 0; p < 2; ++p) { 3811 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); 3812 } 3813 #endif 3814 ++newp; 3815 /* Face H: {a, b, f} */ 3816 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3817 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3818 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3819 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3820 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3821 orntNew[2] = -2; 3822 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3823 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3824 #if 1 3825 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3826 for (p = 0; p < 3; ++p) { 3827 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); 3828 } 3829 #endif 3830 supportNew[0] = (c - cStart)*8 + 1+4; 3831 supportNew[1] = (c - cStart)*8 + 2+4; 3832 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3833 #if 1 3834 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3835 for (p = 0; p < 2; ++p) { 3836 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); 3837 } 3838 #endif 3839 ++newp; 3840 } 3841 /* Hybrid split faces have 4 edges and same cells */ 3842 for (f = fMax; f < fEnd; ++f) { 3843 const PetscInt *cone, *ornt, *support; 3844 PetscInt coneNew[4], orntNew[4]; 3845 PetscInt supportNew[2], size, s, c; 3846 3847 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3848 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3849 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3850 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3851 for (r = 0; r < 2; ++r) { 3852 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3853 3854 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3855 orntNew[0] = ornt[0]; 3856 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3857 orntNew[1] = ornt[1]; 3858 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3859 orntNew[2+r] = 0; 3860 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3861 orntNew[3-r] = 0; 3862 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3863 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3864 #if 1 3865 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3866 for (p = 0; p < 2; ++p) { 3867 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); 3868 } 3869 for (p = 2; p < 4; ++p) { 3870 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); 3871 } 3872 #endif 3873 for (s = 0; s < size; ++s) { 3874 const PetscInt *coneCell, *orntCell, *fornt; 3875 PetscInt o, of; 3876 3877 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3878 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3879 o = orntCell[0] < 0 ? -1 : 1; 3880 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3881 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3882 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3883 of = fornt[c-2] < 0 ? -1 : 1; 3884 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3885 } 3886 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3887 #if 1 3888 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3889 for (p = 0; p < size; ++p) { 3890 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); 3891 } 3892 #endif 3893 } 3894 } 3895 /* Hybrid cell faces have 4 edges and 2 cells */ 3896 for (c = cMax; c < cEnd; ++c) { 3897 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3898 const PetscInt *cone, *ornt; 3899 PetscInt coneNew[4], orntNew[4]; 3900 PetscInt supportNew[2]; 3901 3902 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3903 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3904 for (r = 0; r < 3; ++r) { 3905 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3906 orntNew[0] = 0; 3907 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3908 orntNew[1] = 0; 3909 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3910 orntNew[2] = 0; 3911 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3912 orntNew[3] = 0; 3913 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3914 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3915 #if 1 3916 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); 3917 for (p = 0; p < 2; ++p) { 3918 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); 3919 } 3920 for (p = 2; p < 4; ++p) { 3921 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); 3922 } 3923 #endif 3924 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3925 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3926 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3927 #if 1 3928 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); 3929 for (p = 0; p < 2; ++p) { 3930 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); 3931 } 3932 #endif 3933 } 3934 } 3935 /* Interior split edges have 2 vertices and the same faces as the parent */ 3936 for (e = eStart; e < eMax; ++e) { 3937 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3938 3939 for (r = 0; r < 2; ++r) { 3940 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3941 const PetscInt *cone, *ornt, *support; 3942 PetscInt coneNew[2], coneSize, c, supportSize, s; 3943 3944 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3945 coneNew[0] = vStartNew + (cone[0] - vStart); 3946 coneNew[1] = vStartNew + (cone[1] - vStart); 3947 coneNew[(r+1)%2] = newv; 3948 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3949 #if 1 3950 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3951 for (p = 0; p < 2; ++p) { 3952 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); 3953 } 3954 #endif 3955 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3956 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3957 for (s = 0; s < supportSize; ++s) { 3958 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3959 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3960 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3961 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3962 if (support[s] < fMax) { 3963 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3964 } else { 3965 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3966 } 3967 } 3968 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3969 #if 1 3970 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3971 for (p = 0; p < supportSize; ++p) { 3972 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); 3973 } 3974 #endif 3975 } 3976 } 3977 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3978 for (f = fStart; f < fMax; ++f) { 3979 const PetscInt *cone, *ornt, *support; 3980 PetscInt coneSize, supportSize, s; 3981 3982 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3983 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3984 for (r = 0; r < 3; ++r) { 3985 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3986 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3987 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3988 -1, -1, 1, 6, 0, 4, 3989 2, 5, 3, 4, -1, -1, 3990 -1, -1, 3, 6, 2, 7}; 3991 3992 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3993 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3994 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3995 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3996 #if 1 3997 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3998 for (p = 0; p < 2; ++p) { 3999 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); 4000 } 4001 #endif 4002 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4003 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4004 for (s = 0; s < supportSize; ++s) { 4005 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4006 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4007 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4008 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4009 if (support[s] < cMax) { 4010 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4011 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4012 if (er == eint[c]) { 4013 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4014 } else { 4015 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4016 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4017 } 4018 } else { 4019 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4020 } 4021 } 4022 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4023 #if 1 4024 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4025 for (p = 0; p < intFaces; ++p) { 4026 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); 4027 } 4028 #endif 4029 } 4030 } 4031 /* Interior cell edges have 2 vertices and 4 faces */ 4032 for (c = cStart; c < cMax; ++c) { 4033 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4034 const PetscInt *cone, *ornt, *fcone; 4035 PetscInt coneNew[2], supportNew[4], find; 4036 4037 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4038 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4039 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4040 find = GetTriEdge_Static(ornt[0], 0); 4041 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4042 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4043 find = GetTriEdge_Static(ornt[2], 1); 4044 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4045 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4046 #if 1 4047 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4048 for (p = 0; p < 2; ++p) { 4049 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); 4050 } 4051 #endif 4052 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4053 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4054 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4055 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4056 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4057 #if 1 4058 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4059 for (p = 0; p < 4; ++p) { 4060 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); 4061 } 4062 #endif 4063 } 4064 /* Hybrid edges have two vertices and the same faces */ 4065 for (e = eMax; e < eEnd; ++e) { 4066 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4067 const PetscInt *cone, *support, *fcone; 4068 PetscInt coneNew[2], size, fsize, s; 4069 4070 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4071 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4072 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4073 coneNew[0] = vStartNew + (cone[0] - vStart); 4074 coneNew[1] = vStartNew + (cone[1] - vStart); 4075 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4076 #if 1 4077 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4078 for (p = 0; p < 2; ++p) { 4079 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); 4080 } 4081 #endif 4082 for (s = 0; s < size; ++s) { 4083 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4084 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4085 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4086 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 4087 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4088 } 4089 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4090 #if 1 4091 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4092 for (p = 0; p < size; ++p) { 4093 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); 4094 } 4095 #endif 4096 } 4097 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4098 for (f = fMax; f < fEnd; ++f) { 4099 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4100 const PetscInt *cone, *support, *ccone, *cornt; 4101 PetscInt coneNew[2], size, csize, s; 4102 4103 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4104 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4105 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4106 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4107 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4108 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4109 #if 1 4110 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4111 for (p = 0; p < 2; ++p) { 4112 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); 4113 } 4114 #endif 4115 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4116 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4117 for (s = 0; s < size; ++s) { 4118 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4119 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4120 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4121 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4122 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]); 4123 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4124 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4125 } 4126 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4127 #if 1 4128 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4129 for (p = 0; p < 2+size*2; ++p) { 4130 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); 4131 } 4132 #endif 4133 } 4134 /* Interior vertices have identical supports */ 4135 for (v = vStart; v < vEnd; ++v) { 4136 const PetscInt newp = vStartNew + (v - vStart); 4137 const PetscInt *support, *cone; 4138 PetscInt size, s; 4139 4140 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4141 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4142 for (s = 0; s < size; ++s) { 4143 PetscInt r = 0; 4144 4145 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4146 if (cone[1] == v) r = 1; 4147 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4148 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4149 } 4150 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4151 #if 1 4152 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4153 for (p = 0; p < size; ++p) { 4154 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); 4155 } 4156 #endif 4157 } 4158 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4159 for (e = eStart; e < eMax; ++e) { 4160 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4161 const PetscInt *cone, *support; 4162 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4163 4164 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4165 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4166 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4167 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4168 for (s = 0; s < size; ++s) { 4169 PetscInt r = 0; 4170 4171 if (support[s] < fMax) { 4172 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4173 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4174 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4175 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4176 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4177 faceSize += 2; 4178 } else { 4179 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4180 ++faceSize; 4181 } 4182 } 4183 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4184 for (s = 0; s < starSize*2; s += 2) { 4185 const PetscInt *cone, *ornt; 4186 PetscInt e01, e23; 4187 4188 if ((star[s] >= cStart) && (star[s] < cMax)) { 4189 /* Check edge 0-1 */ 4190 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4191 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4192 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4193 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4194 /* Check edge 2-3 */ 4195 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4196 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4197 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4198 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4199 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 4200 } 4201 } 4202 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4203 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4204 #if 1 4205 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4206 for (p = 0; p < 2+faceSize+cellSize; ++p) { 4207 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); 4208 } 4209 #endif 4210 } 4211 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4212 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4213 break; 4214 case REFINER_SIMPLEX_TO_HEX_3D: 4215 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4216 /* All cells have 6 faces */ 4217 for (c = cStart; c < cEnd; ++c) { 4218 const PetscInt newp = cStartNew + (c - cStart)*4; 4219 const PetscInt *cone, *ornt; 4220 PetscInt coneNew[6]; 4221 PetscInt orntNew[6]; 4222 4223 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4224 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4225 /* A hex */ 4226 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 4227 orntNew[0] = ornt[0] < 0 ? -1 : 1; 4228 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 4229 orntNew[1] = -4; 4230 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 4231 orntNew[2] = ornt[2] < 0 ? -1 : 1; 4232 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 4233 orntNew[3] = -1; 4234 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 4235 orntNew[4] = 0; 4236 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 4237 orntNew[5] = ornt[1] < 0 ? -1 : 1; 4238 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4239 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4240 #if 1 4241 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); 4242 for (p = 0; p < 6; ++p) { 4243 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); 4244 } 4245 #endif 4246 /* B hex */ 4247 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 4248 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4249 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 4250 orntNew[1] = 0; 4251 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 4252 orntNew[2] = 0; 4253 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 4254 orntNew[3] = ornt[3] < 0 ? -2 : 0; 4255 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 4256 orntNew[4] = 0; 4257 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 4258 orntNew[5] = ornt[1] < 0 ? -4 : 2; 4259 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4260 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4261 #if 1 4262 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); 4263 for (p = 0; p < 6; ++p) { 4264 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); 4265 } 4266 #endif 4267 /* C hex */ 4268 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 4269 orntNew[0] = ornt[0] < 0 ? -4 : 2; 4270 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 4271 orntNew[1] = -4; 4272 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 4273 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4274 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 4275 orntNew[3] = -1; 4276 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 4277 orntNew[4] = ornt[3] < 0 ? -1 : 1; 4278 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 4279 orntNew[5] = -4; 4280 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4281 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4282 #if 1 4283 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); 4284 for (p = 0; p < 6; ++p) { 4285 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); 4286 } 4287 #endif 4288 /* D hex */ 4289 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 4290 orntNew[0] = 0; 4291 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 4292 orntNew[1] = ornt[3] < 0 ? -1 : 1; 4293 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 4294 orntNew[2] = ornt[2] < 0 ? -4 : 2; 4295 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 4296 orntNew[3] = -1; 4297 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 4298 orntNew[4] = 0; 4299 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 4300 orntNew[5] = ornt[1] < 0 ? -2 : 0; 4301 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4302 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4303 #if 1 4304 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); 4305 for (p = 0; p < 6; ++p) { 4306 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); 4307 } 4308 #endif 4309 } 4310 /* Split faces have 4 edges and the same cells as the parent */ 4311 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4312 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4313 for (f = fStart; f < fEnd; ++f) { 4314 const PetscInt newp = fStartNew + (f - fStart)*3; 4315 const PetscInt *cone, *ornt, *support; 4316 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 4317 4318 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4319 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4320 /* A quad */ 4321 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4322 orntNew[0] = ornt[2]; 4323 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4324 orntNew[1] = ornt[0]; 4325 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4326 orntNew[2] = 0; 4327 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4328 orntNew[3] = -2; 4329 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4330 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4331 #if 1 4332 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); 4333 for (p = 0; p < 4; ++p) { 4334 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); 4335 } 4336 #endif 4337 /* B quad */ 4338 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4339 orntNew[0] = ornt[0]; 4340 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4341 orntNew[1] = ornt[1]; 4342 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4343 orntNew[2] = 0; 4344 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4345 orntNew[3] = -2; 4346 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4347 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4348 #if 1 4349 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); 4350 for (p = 0; p < 4; ++p) { 4351 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); 4352 } 4353 #endif 4354 /* C quad */ 4355 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4356 orntNew[0] = ornt[1]; 4357 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4358 orntNew[1] = ornt[2]; 4359 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4360 orntNew[2] = 0; 4361 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4362 orntNew[3] = -2; 4363 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4364 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4365 #if 1 4366 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); 4367 for (p = 0; p < 4; ++p) { 4368 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); 4369 } 4370 #endif 4371 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4372 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4373 for (r = 0; r < 3; ++r) { 4374 for (s = 0; s < supportSize; ++s) { 4375 PetscInt subf; 4376 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4377 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4378 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4379 for (c = 0; c < coneSize; ++c) { 4380 if (cone[c] == f) break; 4381 } 4382 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4383 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 4384 } 4385 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4386 #if 1 4387 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); 4388 for (p = 0; p < supportSize; ++p) { 4389 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); 4390 } 4391 #endif 4392 } 4393 } 4394 /* Interior faces have 4 edges and 2 cells */ 4395 for (c = cStart; c < cEnd; ++c) { 4396 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 4397 const PetscInt *cone, *ornt; 4398 PetscInt coneNew[4], orntNew[4]; 4399 PetscInt supportNew[2]; 4400 4401 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4402 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4403 /* Face {a, g, m, h} */ 4404 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 4405 orntNew[0] = 0; 4406 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4407 orntNew[1] = 0; 4408 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4409 orntNew[2] = -2; 4410 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 4411 orntNew[3] = -2; 4412 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4413 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4414 #if 1 4415 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4416 for (p = 0; p < 4; ++p) { 4417 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); 4418 } 4419 #endif 4420 supportNew[0] = (c - cStart)*4 + 0; 4421 supportNew[1] = (c - cStart)*4 + 1; 4422 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4423 #if 1 4424 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4425 for (p = 0; p < 2; ++p) { 4426 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); 4427 } 4428 #endif 4429 ++newp; 4430 /* Face {g, b, l , m} */ 4431 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 4432 orntNew[0] = -2; 4433 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 4434 orntNew[1] = 0; 4435 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4436 orntNew[2] = 0; 4437 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4438 orntNew[3] = -2; 4439 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4440 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4441 #if 1 4442 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4443 for (p = 0; p < 4; ++p) { 4444 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); 4445 } 4446 #endif 4447 supportNew[0] = (c - cStart)*4 + 1; 4448 supportNew[1] = (c - cStart)*4 + 2; 4449 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4450 #if 1 4451 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4452 for (p = 0; p < 2; ++p) { 4453 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); 4454 } 4455 #endif 4456 ++newp; 4457 /* Face {c, g, m, i} */ 4458 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 4459 orntNew[0] = 0; 4460 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4461 orntNew[1] = 0; 4462 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4463 orntNew[2] = -2; 4464 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 4465 orntNew[3] = -2; 4466 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4467 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4468 #if 1 4469 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4470 for (p = 0; p < 4; ++p) { 4471 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); 4472 } 4473 #endif 4474 supportNew[0] = (c - cStart)*4 + 0; 4475 supportNew[1] = (c - cStart)*4 + 2; 4476 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4477 #if 1 4478 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4479 for (p = 0; p < 2; ++p) { 4480 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); 4481 } 4482 #endif 4483 ++newp; 4484 /* Face {d, h, m, i} */ 4485 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 4486 orntNew[0] = 0; 4487 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4488 orntNew[1] = 0; 4489 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4490 orntNew[2] = -2; 4491 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 4492 orntNew[3] = -2; 4493 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4494 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4495 #if 1 4496 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4497 for (p = 0; p < 4; ++p) { 4498 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); 4499 } 4500 #endif 4501 supportNew[0] = (c - cStart)*4 + 0; 4502 supportNew[1] = (c - cStart)*4 + 3; 4503 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4504 #if 1 4505 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4506 for (p = 0; p < 2; ++p) { 4507 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); 4508 } 4509 #endif 4510 ++newp; 4511 /* Face {h, m, l, e} */ 4512 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4513 orntNew[0] = 0; 4514 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4515 orntNew[1] = -2; 4516 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 4517 orntNew[2] = -2; 4518 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 4519 orntNew[3] = 0; 4520 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4521 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4522 #if 1 4523 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4524 for (p = 0; p < 4; ++p) { 4525 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); 4526 } 4527 #endif 4528 supportNew[0] = (c - cStart)*4 + 1; 4529 supportNew[1] = (c - cStart)*4 + 3; 4530 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4531 #if 1 4532 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4533 for (p = 0; p < 2; ++p) { 4534 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); 4535 } 4536 #endif 4537 ++newp; 4538 /* Face {i, m, l, f} */ 4539 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4540 orntNew[0] = 0; 4541 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4542 orntNew[1] = -2; 4543 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 4544 orntNew[2] = -2; 4545 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 4546 orntNew[3] = 0; 4547 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4548 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4549 #if 1 4550 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4551 for (p = 0; p < 4; ++p) { 4552 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); 4553 } 4554 #endif 4555 supportNew[0] = (c - cStart)*4 + 2; 4556 supportNew[1] = (c - cStart)*4 + 3; 4557 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4558 #if 1 4559 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4560 for (p = 0; p < 2; ++p) { 4561 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); 4562 } 4563 #endif 4564 ++newp; 4565 } 4566 /* Split Edges have 2 vertices and the same faces as the parent */ 4567 for (e = eStart; e < eEnd; ++e) { 4568 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4569 4570 for (r = 0; r < 2; ++r) { 4571 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4572 const PetscInt *cone, *ornt, *support; 4573 PetscInt coneNew[2], coneSize, c, supportSize, s; 4574 4575 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4576 coneNew[0] = vStartNew + (cone[0] - vStart); 4577 coneNew[1] = vStartNew + (cone[1] - vStart); 4578 coneNew[(r+1)%2] = newv; 4579 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4580 #if 1 4581 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4582 for (p = 0; p < 2; ++p) { 4583 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); 4584 } 4585 #endif 4586 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4587 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4588 for (s = 0; s < supportSize; ++s) { 4589 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4590 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4591 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4592 for (c = 0; c < coneSize; ++c) { 4593 if (cone[c] == e) break; 4594 } 4595 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4596 } 4597 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4598 #if 1 4599 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4600 for (p = 0; p < supportSize; ++p) { 4601 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); 4602 } 4603 #endif 4604 } 4605 } 4606 /* Face edges have 2 vertices and 2 + cell faces supports */ 4607 for (f = fStart; f < fEnd; ++f) { 4608 const PetscInt *cone, *ornt, *support; 4609 PetscInt coneSize, supportSize, s; 4610 4611 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4612 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4613 for (r = 0; r < 3; ++r) { 4614 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 4615 PetscInt coneNew[2]; 4616 PetscInt fint[4][3] = { {0, 1, 2}, 4617 {3, 4, 0}, 4618 {2, 5, 3}, 4619 {1, 4, 5} }; 4620 4621 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4622 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4623 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 4624 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4625 #if 1 4626 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4627 for (p = 0; p < 2; ++p) { 4628 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); 4629 } 4630 #endif 4631 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 4632 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 4633 for (s = 0; s < supportSize; ++s) { 4634 PetscInt er; 4635 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4636 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4637 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4638 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4639 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 4640 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 4641 } 4642 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4643 #if 1 4644 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4645 for (p = 0; p < supportSize + 2; ++p) { 4646 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); 4647 } 4648 #endif 4649 } 4650 } 4651 /* Interior cell edges have 2 vertices and 3 faces */ 4652 for (c = cStart; c < cEnd; ++c) { 4653 const PetscInt *cone; 4654 PetscInt fint[4][3] = { {0,1,2}, 4655 {0,3,4}, 4656 {2,3,5}, 4657 {1,4,5} } ; 4658 4659 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4660 for (r = 0; r < 4; r++) { 4661 PetscInt coneNew[2], supportNew[3]; 4662 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 4663 4664 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4665 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 4666 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4667 #if 1 4668 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4669 for (p = 0; p < 2; ++p) { 4670 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); 4671 } 4672 #endif 4673 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 4674 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 4675 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 4676 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4677 #if 1 4678 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4679 for (p = 0; p < 3; ++p) { 4680 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); 4681 } 4682 #endif 4683 } 4684 } 4685 /* Old vertices have identical supports */ 4686 for (v = vStart; v < vEnd; ++v) { 4687 const PetscInt newp = vStartNew + (v - vStart); 4688 const PetscInt *support, *cone; 4689 PetscInt size, s; 4690 4691 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4692 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4693 for (s = 0; s < size; ++s) { 4694 PetscInt r = 0; 4695 4696 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4697 if (cone[1] == v) r = 1; 4698 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4699 } 4700 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4701 #if 1 4702 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4703 for (p = 0; p < size; ++p) { 4704 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); 4705 } 4706 #endif 4707 } 4708 /* Edge vertices have 2 + faces supports */ 4709 for (e = eStart; e < eEnd; ++e) { 4710 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4711 const PetscInt *cone, *support; 4712 PetscInt size, s; 4713 4714 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4715 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4716 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4717 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4718 for (s = 0; s < size; ++s) { 4719 PetscInt r = 0, coneSize; 4720 4721 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4722 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4723 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4724 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 4725 } 4726 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4727 #if 1 4728 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4729 for (p = 0; p < 2+size; ++p) { 4730 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); 4731 } 4732 #endif 4733 } 4734 /* Face vertices have 3 + cells supports */ 4735 for (f = fStart; f < fEnd; ++f) { 4736 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4737 const PetscInt *cone, *support; 4738 PetscInt size, s; 4739 4740 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4741 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4742 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4743 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4744 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4745 for (s = 0; s < size; ++s) { 4746 PetscInt r = 0, coneSize; 4747 4748 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4749 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4750 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 4751 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 4752 } 4753 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4754 #if 1 4755 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4756 for (p = 0; p < 3+size; ++p) { 4757 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); 4758 } 4759 #endif 4760 } 4761 /* Interior cell vertices have 4 supports */ 4762 for (c = cStart; c < cEnd; ++c) { 4763 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 4764 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4765 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4766 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4767 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4768 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4769 #if 1 4770 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4771 for (p = 0; p < 4; ++p) { 4772 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); 4773 } 4774 #endif 4775 } 4776 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4777 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4778 break; 4779 case REFINER_HEX_3D: 4780 /* 4781 Bottom (viewed from top) Top 4782 1---------2---------2 7---------2---------6 4783 | | | | | | 4784 | B 2 C | | H 2 G | 4785 | | | | | | 4786 3----3----0----1----1 3----3----0----1----1 4787 | | | | | | 4788 | A 0 D | | E 0 F | 4789 | | | | | | 4790 0---------0---------3 4---------0---------5 4791 */ 4792 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4793 for (c = cStart; c < cEnd; ++c) { 4794 const PetscInt newp = (c - cStart)*8; 4795 const PetscInt *cone, *ornt; 4796 PetscInt coneNew[6], orntNew[6]; 4797 4798 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4799 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4800 /* A hex */ 4801 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4802 orntNew[0] = ornt[0]; 4803 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4804 orntNew[1] = 0; 4805 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4806 orntNew[2] = ornt[2]; 4807 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4808 orntNew[3] = 0; 4809 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4810 orntNew[4] = 0; 4811 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4812 orntNew[5] = ornt[5]; 4813 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4814 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4815 #if 1 4816 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); 4817 for (p = 0; p < 6; ++p) { 4818 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); 4819 } 4820 #endif 4821 /* B hex */ 4822 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4823 orntNew[0] = ornt[0]; 4824 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4825 orntNew[1] = 0; 4826 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4827 orntNew[2] = -1; 4828 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4829 orntNew[3] = ornt[3]; 4830 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4831 orntNew[4] = 0; 4832 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4833 orntNew[5] = ornt[5]; 4834 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4835 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4836 #if 1 4837 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); 4838 for (p = 0; p < 6; ++p) { 4839 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); 4840 } 4841 #endif 4842 /* C hex */ 4843 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4844 orntNew[0] = ornt[0]; 4845 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4846 orntNew[1] = 0; 4847 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4848 orntNew[2] = -1; 4849 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4850 orntNew[3] = ornt[3]; 4851 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4852 orntNew[4] = ornt[4]; 4853 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4854 orntNew[5] = -4; 4855 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4856 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4857 #if 1 4858 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); 4859 for (p = 0; p < 6; ++p) { 4860 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); 4861 } 4862 #endif 4863 /* D hex */ 4864 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4865 orntNew[0] = ornt[0]; 4866 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4867 orntNew[1] = 0; 4868 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4869 orntNew[2] = ornt[2]; 4870 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4871 orntNew[3] = 0; 4872 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4873 orntNew[4] = ornt[4]; 4874 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4875 orntNew[5] = -4; 4876 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4877 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4878 #if 1 4879 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); 4880 for (p = 0; p < 6; ++p) { 4881 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); 4882 } 4883 #endif 4884 /* E hex */ 4885 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4886 orntNew[0] = -4; 4887 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4888 orntNew[1] = ornt[1]; 4889 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4890 orntNew[2] = ornt[2]; 4891 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4892 orntNew[3] = 0; 4893 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4894 orntNew[4] = -1; 4895 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4896 orntNew[5] = ornt[5]; 4897 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4898 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4899 #if 1 4900 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); 4901 for (p = 0; p < 6; ++p) { 4902 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); 4903 } 4904 #endif 4905 /* F hex */ 4906 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4907 orntNew[0] = -4; 4908 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4909 orntNew[1] = ornt[1]; 4910 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4911 orntNew[2] = ornt[2]; 4912 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4913 orntNew[3] = -1; 4914 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4915 orntNew[4] = ornt[4]; 4916 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4917 orntNew[5] = 1; 4918 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4919 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4920 #if 1 4921 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); 4922 for (p = 0; p < 6; ++p) { 4923 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); 4924 } 4925 #endif 4926 /* G hex */ 4927 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4928 orntNew[0] = -4; 4929 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4930 orntNew[1] = ornt[1]; 4931 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4932 orntNew[2] = 0; 4933 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4934 orntNew[3] = ornt[3]; 4935 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4936 orntNew[4] = ornt[4]; 4937 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4938 orntNew[5] = -3; 4939 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4940 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4941 #if 1 4942 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); 4943 for (p = 0; p < 6; ++p) { 4944 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); 4945 } 4946 #endif 4947 /* H hex */ 4948 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4949 orntNew[0] = -4; 4950 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4951 orntNew[1] = ornt[1]; 4952 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4953 orntNew[2] = -1; 4954 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4955 orntNew[3] = ornt[3]; 4956 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4957 orntNew[4] = 3; 4958 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4959 orntNew[5] = ornt[5]; 4960 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4961 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4962 #if 1 4963 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); 4964 for (p = 0; p < 6; ++p) { 4965 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); 4966 } 4967 #endif 4968 } 4969 /* Split faces have 4 edges and the same cells as the parent */ 4970 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4971 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4972 for (f = fStart; f < fEnd; ++f) { 4973 for (r = 0; r < 4; ++r) { 4974 /* TODO: This can come from GetFaces_Internal() */ 4975 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}; 4976 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4977 const PetscInt *cone, *ornt, *support; 4978 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4979 4980 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4981 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4982 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4983 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4984 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4985 orntNew[(r+0)%4] = ornt[r]; 4986 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4987 orntNew[(r+1)%4] = 0; 4988 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4989 orntNew[(r+2)%4] = -2; 4990 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4991 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4992 #if 1 4993 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4994 for (p = 0; p < 4; ++p) { 4995 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); 4996 } 4997 #endif 4998 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4999 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5000 for (s = 0; s < supportSize; ++s) { 5001 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5002 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5003 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5004 for (c = 0; c < coneSize; ++c) { 5005 if (cone[c] == f) break; 5006 } 5007 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 5008 } 5009 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5010 #if 1 5011 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5012 for (p = 0; p < supportSize; ++p) { 5013 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); 5014 } 5015 #endif 5016 } 5017 } 5018 /* Interior faces have 4 edges and 2 cells */ 5019 for (c = cStart; c < cEnd; ++c) { 5020 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}; 5021 const PetscInt *cone, *ornt; 5022 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 5023 5024 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5025 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5026 /* A-D face */ 5027 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 5028 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 5029 orntNew[0] = 0; 5030 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5031 orntNew[1] = 0; 5032 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5033 orntNew[2] = -2; 5034 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 5035 orntNew[3] = -2; 5036 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5037 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5038 #if 1 5039 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5040 for (p = 0; p < 4; ++p) { 5041 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); 5042 } 5043 #endif 5044 /* C-D face */ 5045 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 5046 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 5047 orntNew[0] = 0; 5048 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5049 orntNew[1] = 0; 5050 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5051 orntNew[2] = -2; 5052 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 5053 orntNew[3] = -2; 5054 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5055 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5056 #if 1 5057 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5058 for (p = 0; p < 4; ++p) { 5059 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); 5060 } 5061 #endif 5062 /* B-C face */ 5063 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 5064 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 5065 orntNew[0] = -2; 5066 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 5067 orntNew[1] = 0; 5068 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5069 orntNew[2] = 0; 5070 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5071 orntNew[3] = -2; 5072 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5073 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5074 #if 1 5075 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5076 for (p = 0; p < 4; ++p) { 5077 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); 5078 } 5079 #endif 5080 /* A-B face */ 5081 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 5082 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 5083 orntNew[0] = -2; 5084 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 5085 orntNew[1] = 0; 5086 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5087 orntNew[2] = 0; 5088 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5089 orntNew[3] = -2; 5090 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5091 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5092 #if 1 5093 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5094 for (p = 0; p < 4; ++p) { 5095 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); 5096 } 5097 #endif 5098 /* E-F face */ 5099 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 5100 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5101 orntNew[0] = -2; 5102 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 5103 orntNew[1] = -2; 5104 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 5105 orntNew[2] = 0; 5106 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5107 orntNew[3] = 0; 5108 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5109 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5110 #if 1 5111 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5112 for (p = 0; p < 4; ++p) { 5113 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); 5114 } 5115 #endif 5116 /* F-G face */ 5117 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 5118 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5119 orntNew[0] = -2; 5120 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 5121 orntNew[1] = -2; 5122 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 5123 orntNew[2] = 0; 5124 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5125 orntNew[3] = 0; 5126 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5127 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5128 #if 1 5129 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5130 for (p = 0; p < 4; ++p) { 5131 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); 5132 } 5133 #endif 5134 /* G-H face */ 5135 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 5136 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 5137 orntNew[0] = -2; 5138 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 5139 orntNew[1] = 0; 5140 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5141 orntNew[2] = 0; 5142 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5143 orntNew[3] = -2; 5144 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5145 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5146 #if 1 5147 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5148 for (p = 0; p < 4; ++p) { 5149 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); 5150 } 5151 #endif 5152 /* E-H face */ 5153 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 5154 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5155 orntNew[0] = -2; 5156 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 5157 orntNew[1] = -2; 5158 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 5159 orntNew[2] = 0; 5160 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5161 orntNew[3] = 0; 5162 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5163 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5164 #if 1 5165 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5166 for (p = 0; p < 4; ++p) { 5167 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); 5168 } 5169 #endif 5170 /* A-E face */ 5171 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 5172 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 5173 orntNew[0] = 0; 5174 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5175 orntNew[1] = 0; 5176 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5177 orntNew[2] = -2; 5178 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 5179 orntNew[3] = -2; 5180 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5181 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5182 #if 1 5183 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5184 for (p = 0; p < 4; ++p) { 5185 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); 5186 } 5187 #endif 5188 /* D-F face */ 5189 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 5190 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 5191 orntNew[0] = -2; 5192 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 5193 orntNew[1] = 0; 5194 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5195 orntNew[2] = 0; 5196 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5197 orntNew[3] = -2; 5198 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5199 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5200 #if 1 5201 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5202 for (p = 0; p < 4; ++p) { 5203 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); 5204 } 5205 #endif 5206 /* C-G face */ 5207 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 5208 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5209 orntNew[0] = -2; 5210 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 5211 orntNew[1] = -2; 5212 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 5213 orntNew[2] = 0; 5214 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5215 orntNew[3] = 0; 5216 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5217 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5218 #if 1 5219 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5220 for (p = 0; p < 4; ++p) { 5221 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); 5222 } 5223 #endif 5224 /* B-H face */ 5225 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 5226 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5227 orntNew[0] = 0; 5228 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5229 orntNew[1] = -2; 5230 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 5231 orntNew[2] = -2; 5232 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 5233 orntNew[3] = 0; 5234 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5235 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5236 #if 1 5237 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5238 for (p = 0; p < 4; ++p) { 5239 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); 5240 } 5241 #endif 5242 for (r = 0; r < 12; ++r) { 5243 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 5244 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 5245 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 5246 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5247 #if 1 5248 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5249 for (p = 0; p < 2; ++p) { 5250 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); 5251 } 5252 #endif 5253 } 5254 } 5255 /* Split edges have 2 vertices and the same faces as the parent */ 5256 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5257 for (e = eStart; e < eEnd; ++e) { 5258 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5259 5260 for (r = 0; r < 2; ++r) { 5261 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5262 const PetscInt *cone, *ornt, *support; 5263 PetscInt coneNew[2], coneSize, c, supportSize, s; 5264 5265 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5266 coneNew[0] = vStartNew + (cone[0] - vStart); 5267 coneNew[1] = vStartNew + (cone[1] - vStart); 5268 coneNew[(r+1)%2] = newv; 5269 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5270 #if 1 5271 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5272 for (p = 0; p < 2; ++p) { 5273 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); 5274 } 5275 #endif 5276 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5277 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5278 for (s = 0; s < supportSize; ++s) { 5279 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5280 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5281 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5282 for (c = 0; c < coneSize; ++c) { 5283 if (cone[c] == e) break; 5284 } 5285 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 5286 } 5287 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5288 #if 1 5289 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5290 for (p = 0; p < supportSize; ++p) { 5291 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); 5292 } 5293 #endif 5294 } 5295 } 5296 /* Face edges have 2 vertices and 2+cells faces */ 5297 for (f = fStart; f < fEnd; ++f) { 5298 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}; 5299 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5300 const PetscInt *cone, *coneCell, *orntCell, *support; 5301 PetscInt coneNew[2], coneSize, c, supportSize, s; 5302 5303 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5304 for (r = 0; r < 4; ++r) { 5305 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5306 5307 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5308 coneNew[1] = newv; 5309 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5310 #if 1 5311 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5312 for (p = 0; p < 2; ++p) { 5313 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); 5314 } 5315 #endif 5316 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5317 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5318 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5319 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5320 for (s = 0; s < supportSize; ++s) { 5321 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5322 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5323 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5324 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5325 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5326 } 5327 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5328 #if 1 5329 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5330 for (p = 0; p < 2+supportSize; ++p) { 5331 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); 5332 } 5333 #endif 5334 } 5335 } 5336 /* Cell edges have 2 vertices and 4 faces */ 5337 for (c = cStart; c < cEnd; ++c) { 5338 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}; 5339 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 5340 const PetscInt *cone; 5341 PetscInt coneNew[2], supportNew[4]; 5342 5343 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5344 for (r = 0; r < 6; ++r) { 5345 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 5346 5347 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5348 coneNew[1] = newv; 5349 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5350 #if 1 5351 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5352 for (p = 0; p < 2; ++p) { 5353 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); 5354 } 5355 #endif 5356 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5357 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5358 #if 1 5359 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5360 for (p = 0; p < 4; ++p) { 5361 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); 5362 } 5363 #endif 5364 } 5365 } 5366 /* Old vertices have identical supports */ 5367 for (v = vStart; v < vEnd; ++v) { 5368 const PetscInt newp = vStartNew + (v - vStart); 5369 const PetscInt *support, *cone; 5370 PetscInt size, s; 5371 5372 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5373 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5374 for (s = 0; s < size; ++s) { 5375 PetscInt r = 0; 5376 5377 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5378 if (cone[1] == v) r = 1; 5379 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5380 } 5381 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5382 #if 1 5383 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5384 for (p = 0; p < size; ++p) { 5385 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); 5386 } 5387 #endif 5388 } 5389 /* Edge vertices have 2 + faces supports */ 5390 for (e = eStart; e < eEnd; ++e) { 5391 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5392 const PetscInt *cone, *support; 5393 PetscInt size, s; 5394 5395 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5396 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5397 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5398 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5399 for (s = 0; s < size; ++s) { 5400 PetscInt r; 5401 5402 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5403 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5404 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 5405 } 5406 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5407 #if 1 5408 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5409 for (p = 0; p < 2+size; ++p) { 5410 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); 5411 } 5412 #endif 5413 } 5414 /* Face vertices have 4 + cells supports */ 5415 for (f = fStart; f < fEnd; ++f) { 5416 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5417 const PetscInt *cone, *support; 5418 PetscInt size, s; 5419 5420 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5421 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5422 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5423 for (s = 0; s < size; ++s) { 5424 PetscInt r; 5425 5426 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5427 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5428 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 5429 } 5430 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5431 #if 1 5432 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5433 for (p = 0; p < 4+size; ++p) { 5434 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); 5435 } 5436 #endif 5437 } 5438 /* Cell vertices have 6 supports */ 5439 for (c = cStart; c < cEnd; ++c) { 5440 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 5441 PetscInt supportNew[6]; 5442 5443 for (r = 0; r < 6; ++r) { 5444 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 5445 } 5446 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5447 } 5448 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5449 break; 5450 case REFINER_HYBRID_HEX_3D: 5451 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 5452 /* 5453 Bottom (viewed from top) Top 5454 1---------2---------2 7---------2---------6 5455 | | | | | | 5456 | B 2 C | | H 2 G | 5457 | | | | | | 5458 3----3----0----1----1 3----3----0----1----1 5459 | | | | | | 5460 | A 0 D | | E 0 F | 5461 | | | | | | 5462 0---------0---------3 4---------0---------5 5463 */ 5464 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 5465 for (c = cStart; c < cMax; ++c) { 5466 const PetscInt newp = (c - cStart)*8; 5467 const PetscInt *cone, *ornt; 5468 PetscInt coneNew[6], orntNew[6]; 5469 5470 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5471 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5472 /* A hex */ 5473 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 5474 orntNew[0] = ornt[0]; 5475 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 5476 orntNew[1] = 0; 5477 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 5478 orntNew[2] = ornt[2]; 5479 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 5480 orntNew[3] = 0; 5481 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 5482 orntNew[4] = 0; 5483 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 5484 orntNew[5] = ornt[5]; 5485 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5486 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5487 #if 1 5488 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); 5489 for (p = 0; p < 6; ++p) { 5490 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); 5491 } 5492 #endif 5493 /* B hex */ 5494 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 5495 orntNew[0] = ornt[0]; 5496 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5497 orntNew[1] = 0; 5498 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 5499 orntNew[2] = -1; 5500 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 5501 orntNew[3] = ornt[3]; 5502 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 5503 orntNew[4] = 0; 5504 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 5505 orntNew[5] = ornt[5]; 5506 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5507 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5508 #if 1 5509 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); 5510 for (p = 0; p < 6; ++p) { 5511 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); 5512 } 5513 #endif 5514 /* C hex */ 5515 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 5516 orntNew[0] = ornt[0]; 5517 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 5518 orntNew[1] = 0; 5519 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 5520 orntNew[2] = -1; 5521 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 5522 orntNew[3] = ornt[3]; 5523 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 5524 orntNew[4] = ornt[4]; 5525 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 5526 orntNew[5] = -4; 5527 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5528 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5529 #if 1 5530 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); 5531 for (p = 0; p < 6; ++p) { 5532 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); 5533 } 5534 #endif 5535 /* D hex */ 5536 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 5537 orntNew[0] = ornt[0]; 5538 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 5539 orntNew[1] = 0; 5540 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 5541 orntNew[2] = ornt[2]; 5542 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 5543 orntNew[3] = 0; 5544 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 5545 orntNew[4] = ornt[4]; 5546 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 5547 orntNew[5] = -4; 5548 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5549 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5550 #if 1 5551 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); 5552 for (p = 0; p < 6; ++p) { 5553 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); 5554 } 5555 #endif 5556 /* E hex */ 5557 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 5558 orntNew[0] = -4; 5559 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 5560 orntNew[1] = ornt[1]; 5561 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 5562 orntNew[2] = ornt[2]; 5563 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5564 orntNew[3] = 0; 5565 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 5566 orntNew[4] = -1; 5567 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 5568 orntNew[5] = ornt[5]; 5569 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 5570 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 5571 #if 1 5572 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); 5573 for (p = 0; p < 6; ++p) { 5574 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); 5575 } 5576 #endif 5577 /* F hex */ 5578 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 5579 orntNew[0] = -4; 5580 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 5581 orntNew[1] = ornt[1]; 5582 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 5583 orntNew[2] = ornt[2]; 5584 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5585 orntNew[3] = -1; 5586 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 5587 orntNew[4] = ornt[4]; 5588 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 5589 orntNew[5] = 1; 5590 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 5591 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 5592 #if 1 5593 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); 5594 for (p = 0; p < 6; ++p) { 5595 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); 5596 } 5597 #endif 5598 /* G hex */ 5599 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 5600 orntNew[0] = -4; 5601 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 5602 orntNew[1] = ornt[1]; 5603 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5604 orntNew[2] = 0; 5605 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 5606 orntNew[3] = ornt[3]; 5607 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 5608 orntNew[4] = ornt[4]; 5609 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5610 orntNew[5] = -3; 5611 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 5612 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 5613 #if 1 5614 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); 5615 for (p = 0; p < 6; ++p) { 5616 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); 5617 } 5618 #endif 5619 /* H hex */ 5620 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5621 orntNew[0] = -4; 5622 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 5623 orntNew[1] = ornt[1]; 5624 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5625 orntNew[2] = -1; 5626 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 5627 orntNew[3] = ornt[3]; 5628 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5629 orntNew[4] = 3; 5630 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 5631 orntNew[5] = ornt[5]; 5632 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 5633 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 5634 #if 1 5635 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); 5636 for (p = 0; p < 6; ++p) { 5637 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); 5638 } 5639 #endif 5640 } 5641 /* Hybrid cells have 6 faces: Front, Back, Sides */ 5642 /* 5643 3---------2---------2 5644 | | | 5645 | D 2 C | 5646 | | | 5647 3----3----0----1----1 5648 | | | 5649 | A 0 B | 5650 | | | 5651 0---------0---------1 5652 */ 5653 for (c = cMax; c < cEnd; ++c) { 5654 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 5655 const PetscInt *cone, *ornt, *fornt; 5656 PetscInt coneNew[6], orntNew[6], o, of, i; 5657 5658 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5659 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5660 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 5661 o = ornt[0] < 0 ? -1 : 1; 5662 for (r = 0; r < 4; ++r) { 5663 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 5664 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 5665 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 5666 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]); 5667 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 5668 orntNew[0] = ornt[0]; 5669 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 5670 orntNew[1] = ornt[0]; 5671 of = fornt[edgeA] < 0 ? -1 : 1; 5672 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 5673 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 5674 orntNew[i] = ornt[edgeA]; 5675 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 5676 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 5677 orntNew[i] = 0; 5678 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 5679 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 5680 orntNew[i] = -2; 5681 of = fornt[edgeB] < 0 ? -1 : 1; 5682 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 5683 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 5684 orntNew[i] = ornt[edgeB]; 5685 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 5686 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 5687 #if 1 5688 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); 5689 for (p = 0; p < 2; ++p) { 5690 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); 5691 } 5692 for (p = 2; p < 6; ++p) { 5693 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); 5694 } 5695 #endif 5696 } 5697 } 5698 /* Interior split faces have 4 edges and the same cells as the parent */ 5699 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5700 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5701 for (f = fStart; f < fMax; ++f) { 5702 for (r = 0; r < 4; ++r) { 5703 /* TODO: This can come from GetFaces_Internal() */ 5704 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}; 5705 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 5706 const PetscInt *cone, *ornt, *support; 5707 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 5708 5709 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5710 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5711 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 5712 orntNew[(r+3)%4] = ornt[(r+3)%4]; 5713 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 5714 orntNew[(r+0)%4] = ornt[r]; 5715 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5716 orntNew[(r+1)%4] = 0; 5717 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 5718 orntNew[(r+2)%4] = -2; 5719 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5720 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5721 #if 1 5722 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5723 for (p = 0; p < 4; ++p) { 5724 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); 5725 } 5726 #endif 5727 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5728 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5729 for (s = 0; s < supportSize; ++s) { 5730 PetscInt subf; 5731 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5732 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5733 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5734 for (c = 0; c < coneSize; ++c) { 5735 if (cone[c] == f) break; 5736 } 5737 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 5738 if (support[s] < cMax) { 5739 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 5740 } else { 5741 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 5742 } 5743 } 5744 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5745 #if 1 5746 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5747 for (p = 0; p < supportSize; ++p) { 5748 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); 5749 } 5750 #endif 5751 } 5752 } 5753 /* Interior cell faces have 4 edges and 2 cells */ 5754 for (c = cStart; c < cMax; ++c) { 5755 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}; 5756 const PetscInt *cone, *ornt; 5757 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 5758 5759 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5760 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5761 /* A-D face */ 5762 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 5763 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 5764 orntNew[0] = 0; 5765 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5766 orntNew[1] = 0; 5767 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5768 orntNew[2] = -2; 5769 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 5770 orntNew[3] = -2; 5771 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5772 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5773 #if 1 5774 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5775 for (p = 0; p < 4; ++p) { 5776 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); 5777 } 5778 #endif 5779 /* C-D face */ 5780 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 5781 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 5782 orntNew[0] = 0; 5783 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5784 orntNew[1] = 0; 5785 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5786 orntNew[2] = -2; 5787 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 5788 orntNew[3] = -2; 5789 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5790 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5791 #if 1 5792 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5793 for (p = 0; p < 4; ++p) { 5794 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); 5795 } 5796 #endif 5797 /* B-C face */ 5798 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 5799 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 5800 orntNew[0] = -2; 5801 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 5802 orntNew[1] = 0; 5803 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5804 orntNew[2] = 0; 5805 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5806 orntNew[3] = -2; 5807 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5808 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5809 #if 1 5810 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5811 for (p = 0; p < 4; ++p) { 5812 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); 5813 } 5814 #endif 5815 /* A-B face */ 5816 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 5817 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 5818 orntNew[0] = -2; 5819 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 5820 orntNew[1] = 0; 5821 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5822 orntNew[2] = 0; 5823 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5824 orntNew[3] = -2; 5825 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5826 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5827 #if 1 5828 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5829 for (p = 0; p < 4; ++p) { 5830 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); 5831 } 5832 #endif 5833 /* E-F face */ 5834 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 5835 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5836 orntNew[0] = -2; 5837 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 5838 orntNew[1] = -2; 5839 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 5840 orntNew[2] = 0; 5841 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5842 orntNew[3] = 0; 5843 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5844 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5845 #if 1 5846 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5847 for (p = 0; p < 4; ++p) { 5848 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); 5849 } 5850 #endif 5851 /* F-G face */ 5852 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 5853 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5854 orntNew[0] = -2; 5855 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 5856 orntNew[1] = -2; 5857 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 5858 orntNew[2] = 0; 5859 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5860 orntNew[3] = 0; 5861 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5862 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5863 #if 1 5864 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5865 for (p = 0; p < 4; ++p) { 5866 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); 5867 } 5868 #endif 5869 /* G-H face */ 5870 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 5871 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 5872 orntNew[0] = -2; 5873 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 5874 orntNew[1] = 0; 5875 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5876 orntNew[2] = 0; 5877 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5878 orntNew[3] = -2; 5879 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5880 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5881 #if 1 5882 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5883 for (p = 0; p < 4; ++p) { 5884 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); 5885 } 5886 #endif 5887 /* E-H face */ 5888 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 5889 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5890 orntNew[0] = -2; 5891 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 5892 orntNew[1] = -2; 5893 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 5894 orntNew[2] = 0; 5895 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5896 orntNew[3] = 0; 5897 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5898 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5899 #if 1 5900 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5901 for (p = 0; p < 4; ++p) { 5902 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); 5903 } 5904 #endif 5905 /* A-E face */ 5906 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 5907 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 5908 orntNew[0] = 0; 5909 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5910 orntNew[1] = 0; 5911 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5912 orntNew[2] = -2; 5913 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 5914 orntNew[3] = -2; 5915 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5916 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5917 #if 1 5918 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5919 for (p = 0; p < 4; ++p) { 5920 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); 5921 } 5922 #endif 5923 /* D-F face */ 5924 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 5925 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 5926 orntNew[0] = -2; 5927 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 5928 orntNew[1] = 0; 5929 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5930 orntNew[2] = 0; 5931 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5932 orntNew[3] = -2; 5933 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5934 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5935 #if 1 5936 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5937 for (p = 0; p < 4; ++p) { 5938 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); 5939 } 5940 #endif 5941 /* C-G face */ 5942 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 5943 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5944 orntNew[0] = -2; 5945 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 5946 orntNew[1] = -2; 5947 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 5948 orntNew[2] = 0; 5949 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5950 orntNew[3] = 0; 5951 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5952 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5953 #if 1 5954 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5955 for (p = 0; p < 4; ++p) { 5956 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); 5957 } 5958 #endif 5959 /* B-H face */ 5960 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 5961 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5962 orntNew[0] = 0; 5963 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5964 orntNew[1] = -2; 5965 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 5966 orntNew[2] = -2; 5967 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 5968 orntNew[3] = 0; 5969 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5970 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5971 #if 1 5972 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5973 for (p = 0; p < 4; ++p) { 5974 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); 5975 } 5976 #endif 5977 for (r = 0; r < 12; ++r) { 5978 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 5979 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 5980 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 5981 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5982 #if 1 5983 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5984 for (p = 0; p < 2; ++p) { 5985 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); 5986 } 5987 #endif 5988 } 5989 } 5990 /* Hybrid split faces have 4 edges and same cells */ 5991 for (f = fMax; f < fEnd; ++f) { 5992 const PetscInt *cone, *ornt, *support; 5993 PetscInt coneNew[4], orntNew[4]; 5994 PetscInt supportNew[2], size, s, c; 5995 5996 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5997 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5998 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5999 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6000 for (r = 0; r < 2; ++r) { 6001 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 6002 6003 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 6004 orntNew[0] = ornt[0]; 6005 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 6006 orntNew[1] = ornt[1]; 6007 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 6008 orntNew[2+r] = 0; 6009 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 6010 orntNew[3-r] = 0; 6011 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6012 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6013 #if 1 6014 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 6015 for (p = 0; p < 2; ++p) { 6016 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); 6017 } 6018 for (p = 2; p < 4; ++p) { 6019 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); 6020 } 6021 #endif 6022 for (s = 0; s < size; ++s) { 6023 const PetscInt *coneCell, *orntCell, *fornt; 6024 PetscInt o, of; 6025 6026 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6027 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6028 o = orntCell[0] < 0 ? -1 : 1; 6029 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 6030 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 6031 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 6032 of = fornt[c-2] < 0 ? -1 : 1; 6033 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 6034 } 6035 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6036 #if 1 6037 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 6038 for (p = 0; p < size; ++p) { 6039 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); 6040 } 6041 #endif 6042 } 6043 } 6044 /* Hybrid cell faces have 4 edges and 2 cells */ 6045 for (c = cMax; c < cEnd; ++c) { 6046 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 6047 const PetscInt *cone, *ornt; 6048 PetscInt coneNew[4], orntNew[4]; 6049 PetscInt supportNew[2]; 6050 6051 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6052 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6053 for (r = 0; r < 4; ++r) { 6054 #if 0 6055 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 6056 orntNew[0] = 0; 6057 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 6058 orntNew[1] = 0; 6059 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 6060 orntNew[2] = 0; 6061 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6062 orntNew[3] = 0; 6063 #else 6064 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 6065 orntNew[0] = 0; 6066 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 6067 orntNew[1] = 0; 6068 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 6069 orntNew[2] = 0; 6070 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6071 orntNew[3] = 0; 6072 #endif 6073 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 6074 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 6075 #if 1 6076 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); 6077 for (p = 0; p < 2; ++p) { 6078 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); 6079 } 6080 for (p = 2; p < 4; ++p) { 6081 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); 6082 } 6083 #endif 6084 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 6085 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 6086 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 6087 #if 1 6088 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); 6089 for (p = 0; p < 2; ++p) { 6090 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); 6091 } 6092 #endif 6093 } 6094 } 6095 /* Interior split edges have 2 vertices and the same faces as the parent */ 6096 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6097 for (e = eStart; e < eMax; ++e) { 6098 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6099 6100 for (r = 0; r < 2; ++r) { 6101 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6102 const PetscInt *cone, *ornt, *support; 6103 PetscInt coneNew[2], coneSize, c, supportSize, s; 6104 6105 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6106 coneNew[0] = vStartNew + (cone[0] - vStart); 6107 coneNew[1] = vStartNew + (cone[1] - vStart); 6108 coneNew[(r+1)%2] = newv; 6109 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6110 #if 1 6111 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6112 for (p = 0; p < 2; ++p) { 6113 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); 6114 } 6115 #endif 6116 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6117 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6118 for (s = 0; s < supportSize; ++s) { 6119 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6120 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6121 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6122 for (c = 0; c < coneSize; ++c) { 6123 if (cone[c] == e) break; 6124 } 6125 if (support[s] < fMax) { 6126 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 6127 } else { 6128 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6129 } 6130 } 6131 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6132 #if 1 6133 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6134 for (p = 0; p < supportSize; ++p) { 6135 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); 6136 } 6137 #endif 6138 } 6139 } 6140 /* Interior face edges have 2 vertices and 2+cells faces */ 6141 for (f = fStart; f < fMax; ++f) { 6142 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}; 6143 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6144 const PetscInt *cone, *coneCell, *orntCell, *support; 6145 PetscInt coneNew[2], coneSize, c, supportSize, s; 6146 6147 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6148 for (r = 0; r < 4; ++r) { 6149 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 6150 6151 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6152 coneNew[1] = newv; 6153 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6154 #if 1 6155 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6156 for (p = 0; p < 2; ++p) { 6157 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); 6158 } 6159 #endif 6160 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6161 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6162 supportRef[0] = fStartNew + (f - fStart)*4 + r; 6163 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 6164 for (s = 0; s < supportSize; ++s) { 6165 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6166 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6167 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6168 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 6169 if (support[s] < cMax) { 6170 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 6171 } else { 6172 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 6173 } 6174 } 6175 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6176 #if 1 6177 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6178 for (p = 0; p < 2+supportSize; ++p) { 6179 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); 6180 } 6181 #endif 6182 } 6183 } 6184 /* Interior cell edges have 2 vertices and 4 faces */ 6185 for (c = cStart; c < cMax; ++c) { 6186 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}; 6187 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 6188 const PetscInt *cone; 6189 PetscInt coneNew[2], supportNew[4]; 6190 6191 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6192 for (r = 0; r < 6; ++r) { 6193 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 6194 6195 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6196 coneNew[1] = newv; 6197 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6198 #if 1 6199 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6200 for (p = 0; p < 2; ++p) { 6201 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); 6202 } 6203 #endif 6204 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 6205 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6206 #if 1 6207 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6208 for (p = 0; p < 4; ++p) { 6209 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); 6210 } 6211 #endif 6212 } 6213 } 6214 /* Hybrid edges have two vertices and the same faces */ 6215 for (e = eMax; e < eEnd; ++e) { 6216 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 6217 const PetscInt *cone, *support, *fcone; 6218 PetscInt coneNew[2], size, fsize, s; 6219 6220 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6221 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6222 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6223 coneNew[0] = vStartNew + (cone[0] - vStart); 6224 coneNew[1] = vStartNew + (cone[1] - vStart); 6225 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6226 #if 1 6227 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6228 for (p = 0; p < 2; ++p) { 6229 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); 6230 } 6231 #endif 6232 for (s = 0; s < size; ++s) { 6233 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6234 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6235 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6236 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 6237 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 6238 } 6239 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6240 #if 1 6241 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6242 for (p = 0; p < size; ++p) { 6243 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); 6244 } 6245 #endif 6246 } 6247 /* Hybrid face edges have 2 vertices and 2+cells faces */ 6248 for (f = fMax; f < fEnd; ++f) { 6249 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 6250 const PetscInt *cone, *support, *ccone, *cornt; 6251 PetscInt coneNew[2], size, csize, s; 6252 6253 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6254 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6255 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6256 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6257 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6258 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6259 #if 1 6260 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6261 for (p = 0; p < 2; ++p) { 6262 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); 6263 } 6264 #endif 6265 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 6266 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 6267 for (s = 0; s < size; ++s) { 6268 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 6269 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 6270 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 6271 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 6272 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]); 6273 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 6274 } 6275 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6276 #if 1 6277 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6278 for (p = 0; p < 2+size; ++p) { 6279 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); 6280 } 6281 #endif 6282 } 6283 /* Hybrid cell edges have 2 vertices and 4 faces */ 6284 for (c = cMax; c < cEnd; ++c) { 6285 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6286 const PetscInt *cone, *support; 6287 PetscInt coneNew[2], size; 6288 6289 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6290 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 6291 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 6292 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6293 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6294 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6295 #if 1 6296 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6297 for (p = 0; p < 2; ++p) { 6298 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); 6299 } 6300 #endif 6301 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 6302 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 6303 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 6304 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 6305 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6306 #if 1 6307 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6308 for (p = 0; p < 4; ++p) { 6309 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); 6310 } 6311 #endif 6312 } 6313 /* Interior vertices have identical supports */ 6314 for (v = vStart; v < vEnd; ++v) { 6315 const PetscInt newp = vStartNew + (v - vStart); 6316 const PetscInt *support, *cone; 6317 PetscInt size, s; 6318 6319 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6320 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6321 for (s = 0; s < size; ++s) { 6322 PetscInt r = 0; 6323 6324 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6325 if (cone[1] == v) r = 1; 6326 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 6327 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 6328 } 6329 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6330 #if 1 6331 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6332 for (p = 0; p < size; ++p) { 6333 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); 6334 } 6335 #endif 6336 } 6337 /* Interior edge vertices have 2 + faces supports */ 6338 for (e = eStart; e < eMax; ++e) { 6339 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6340 const PetscInt *cone, *support; 6341 PetscInt size, s; 6342 6343 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6344 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6345 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6346 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6347 for (s = 0; s < size; ++s) { 6348 PetscInt r; 6349 6350 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6351 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 6352 if (support[s] < fMax) { 6353 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 6354 } else { 6355 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 6356 } 6357 } 6358 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6359 #if 1 6360 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6361 for (p = 0; p < 2+size; ++p) { 6362 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); 6363 } 6364 #endif 6365 } 6366 /* Interior face vertices have 4 + cells supports */ 6367 for (f = fStart; f < fMax; ++f) { 6368 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6369 const PetscInt *cone, *support; 6370 PetscInt size, s; 6371 6372 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6373 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6374 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 6375 for (s = 0; s < size; ++s) { 6376 PetscInt r; 6377 6378 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6379 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 6380 if (support[s] < cMax) { 6381 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 6382 } else { 6383 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 6384 } 6385 } 6386 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6387 #if 1 6388 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6389 for (p = 0; p < 4+size; ++p) { 6390 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); 6391 } 6392 #endif 6393 } 6394 /* Cell vertices have 6 supports */ 6395 for (c = cStart; c < cMax; ++c) { 6396 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 6397 PetscInt supportNew[6]; 6398 6399 for (r = 0; r < 6; ++r) { 6400 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 6401 } 6402 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6403 } 6404 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6405 break; 6406 default: 6407 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6408 } 6409 PetscFunctionReturn(0); 6410 } 6411 6412 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6413 { 6414 PetscSection coordSection, coordSectionNew; 6415 Vec coordinates, coordinatesNew; 6416 PetscScalar *coords, *coordsNew; 6417 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 6418 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 6419 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 6420 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 6421 VecType vtype; 6422 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 6423 const PetscReal *maxCell, *L; 6424 const DMBoundaryType *bd; 6425 PetscErrorCode ierr; 6426 6427 PetscFunctionBegin; 6428 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6429 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6430 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6431 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6432 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6433 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6434 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 6435 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 6436 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 6437 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 6438 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 6439 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 6440 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 6441 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 6442 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 6443 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 6444 /* Determine if we need to localize coordinates when generating them */ 6445 if (isperiodic && !maxCell) { 6446 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 6447 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 6448 } 6449 if (localize) { 6450 PetscInt p, r, newp, *pi; 6451 6452 /* New coordinates will be already localized on the cell */ 6453 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 6454 6455 /* We need the parentId to properly localize coordinates */ 6456 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 6457 switch (refiner) { 6458 case REFINER_NOOP: 6459 break; 6460 case REFINER_SIMPLEX_1D: 6461 for (p = cStart; p < cEnd; ++p) { 6462 for (r = 0; r < 2; ++r) { 6463 newp = (p - cStart)*2 + r; 6464 pi[newp] = p; 6465 } 6466 } 6467 break; 6468 case REFINER_SIMPLEX_2D: 6469 for (p = cStart; p < cEnd; ++p) { 6470 for (r = 0; r < 4; ++r) { 6471 newp = (p - cStart)*4 + r; 6472 pi[newp] = p; 6473 } 6474 } 6475 break; 6476 case REFINER_HEX_2D: 6477 for (p = cStart; p < cEnd; ++p) { 6478 for (r = 0; r < 4; ++r) { 6479 newp = (p - cStart)*4 + r; 6480 pi[newp] = p; 6481 } 6482 } 6483 break; 6484 case REFINER_HYBRID_SIMPLEX_2D: 6485 for (p = cStart; p < cMax; ++p) { 6486 for (r = 0; r < 4; ++r) { 6487 newp = (p - cStart)*4 + r; 6488 pi[newp] = p; 6489 } 6490 } 6491 for (p = cMax; p < cEnd; ++p) { 6492 for (r = 0; r < 2; ++r) { 6493 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 6494 pi[newp] = p; 6495 } 6496 } 6497 break; 6498 case REFINER_HYBRID_HEX_2D: 6499 for (p = cStart; p < cMax; ++p) { 6500 for (r = 0; r < 4; ++r) { 6501 newp = (p - cStart)*4 + r; 6502 pi[newp] = p; 6503 } 6504 } 6505 for (p = cMax; p < cEnd; ++p) { 6506 for (r = 0; r < 2; ++r) { 6507 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 6508 pi[newp] = p; 6509 } 6510 } 6511 break; 6512 case REFINER_SIMPLEX_3D: 6513 for (p = cStart; p < cEnd; ++p) { 6514 for (r = 0; r < 8; ++r) { 6515 newp = (p - cStart)*8 + r; 6516 pi[newp] = p; 6517 } 6518 } 6519 break; 6520 case REFINER_HYBRID_SIMPLEX_3D: 6521 for (p = cStart; p < cMax; ++p) { 6522 for (r = 0; r < 8; ++r) { 6523 newp = (p - cStart)*8 + r; 6524 pi[newp] = p; 6525 } 6526 } 6527 for (p = cMax; p < cEnd; ++p) { 6528 for (r = 0; r < 4; ++r) { 6529 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 6530 pi[newp] = p; 6531 } 6532 } 6533 break; 6534 case REFINER_HEX_3D: 6535 for (p = cStart; p < cEnd; ++p) { 6536 for (r = 0; r < 8; ++r) { 6537 newp = (p - cStart)*8 + r; 6538 pi[newp] = p; 6539 } 6540 } 6541 break; 6542 case REFINER_HYBRID_HEX_3D: 6543 for (p = cStart; p < cMax; ++p) { 6544 for (r = 0; r < 8; ++r) { 6545 newp = (p - cStart)*8 + r; 6546 pi[newp] = p; 6547 } 6548 } 6549 for (p = cMax; p < cEnd; ++p) { 6550 for (r = 0; r < 4; ++r) { 6551 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 6552 pi[newp] = p; 6553 } 6554 } 6555 break; 6556 default: 6557 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6558 } 6559 parentId = pi; 6560 } else { 6561 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 6562 } 6563 if (cMax < 0) cMax = cEnd; 6564 if (fMax < 0) fMax = fEnd; 6565 if (eMax < 0) eMax = eEnd; 6566 6567 /* All vertices have the spaceDim coordinates */ 6568 if (localize) { 6569 PetscInt c; 6570 6571 for (c = cStartNew; c < cEndNew; ++c) { 6572 PetscInt *cone = NULL; 6573 PetscInt closureSize, coneSize = 0, p, pdof; 6574 6575 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 6576 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 6577 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6578 for (p = 0; p < closureSize*2; p += 2) { 6579 const PetscInt point = cone[p]; 6580 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 6581 } 6582 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6583 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 6584 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 6585 } 6586 } 6587 } 6588 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 6589 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 6590 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 6591 } 6592 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 6593 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 6594 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 6595 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 6596 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 6597 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 6598 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 6599 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 6600 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 6601 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 6602 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 6603 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 6604 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 6605 6606 switch (refiner) { 6607 case REFINER_NOOP: break; 6608 case REFINER_SIMPLEX_TO_HEX_3D: 6609 case REFINER_HEX_3D: 6610 case REFINER_HYBRID_HEX_3D: 6611 /* Face vertices have the average of corner coordinates */ 6612 for (f = fStart; f < fMax; ++f) { 6613 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6614 PetscInt *cone = NULL; 6615 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 6616 6617 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6618 for (p = 0; p < closureSize*2; p += 2) { 6619 const PetscInt point = cone[p]; 6620 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6621 } 6622 if (localize) { 6623 const PetscInt *support = NULL; 6624 PetscInt *rStar = NULL; 6625 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 6626 PetscBool cellfound = PETSC_FALSE; 6627 6628 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6629 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 6630 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 6631 /* Compute average of coordinates for each cell sharing the face */ 6632 for (s = 0; s < supportSize; ++s) { 6633 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 6634 PetscInt *cellCone = NULL; 6635 PetscInt cellClosureSize, cellConeSize = 0, cdof; 6636 const PetscInt cell = support[s]; 6637 PetscBool copyoff = PETSC_FALSE; 6638 6639 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6640 for (p = 0; p < cellClosureSize*2; p += 2) { 6641 const PetscInt point = cellCone[p]; 6642 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 6643 } 6644 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 6645 if (!cdof) { /* the parent cell does not have localized coordinates */ 6646 cellfound = PETSC_TRUE; 6647 for (v = 0; v < coneSize; ++v) { 6648 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6649 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 6650 } 6651 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 6652 } else { 6653 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 6654 for (p = 0; p < coneSize; ++p) { 6655 const PetscInt tv = cone[p]; 6656 PetscInt cv, voff; 6657 PetscBool locv = PETSC_TRUE; 6658 6659 for (cv = 0; cv < cellConeSize; ++cv) { 6660 if (cellCone[cv] == tv) { 6661 ccoff[p] = spaceDim*cv + coff; 6662 break; 6663 } 6664 } 6665 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D\n",tv); 6666 6667 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 6668 for (d = 0; d < spaceDim; ++d) { 6669 coordsNewAux[d] += coords[ccoff[p]+d]; 6670 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 6671 } 6672 if (locv && !cellfound) { 6673 cellfound = PETSC_TRUE; 6674 copyoff = PETSC_TRUE; 6675 } 6676 } 6677 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 6678 6679 /* Found a valid face for the "vertex" part of the Section (physical space) 6680 i.e., a face that has at least one corner in the physical space */ 6681 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 6682 } 6683 6684 /* Localize new coordinates on each refined cell */ 6685 for (v = 0; v < rStarSize*2; v += 2) { 6686 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 6687 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 6688 const PetscInt rcell = rStar[v]; 6689 6690 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 6691 if (!rcdof) continue; 6692 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 6693 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6694 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 6695 if (rcone[p] == newv) { 6696 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 6697 break; 6698 } 6699 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 6700 } 6701 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6702 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6703 } 6704 } 6705 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6706 } 6707 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6708 if (!cellfound) { 6709 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 6710 needcoords = PETSC_TRUE; 6711 coneSize = 0; 6712 } 6713 } else { 6714 for (v = 0; v < coneSize; ++v) { 6715 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6716 } 6717 } 6718 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6719 if (coneSize) { 6720 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6721 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6722 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6723 } else { 6724 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 6725 } 6726 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6727 } 6728 case REFINER_SIMPLEX_TO_HEX_2D: 6729 case REFINER_HEX_2D: 6730 case REFINER_HYBRID_HEX_2D: 6731 case REFINER_SIMPLEX_1D: 6732 /* Cell vertices have the average of corner coordinates */ 6733 for (c = cStart; c < cMax; ++c) { 6734 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 6735 PetscInt *cone = NULL; 6736 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 6737 6738 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6739 for (p = 0; p < closureSize*2; p += 2) { 6740 const PetscInt point = cone[p]; 6741 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6742 } 6743 if (localize) { 6744 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 6745 } 6746 if (cdof) { 6747 PetscInt coff; 6748 6749 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 6750 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 6751 } else { 6752 for (v = 0; v < coneSize; ++v) { 6753 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6754 } 6755 } 6756 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6757 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6758 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6759 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6760 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6761 6762 /* Localize new coordinates on each refined cell */ 6763 if (cdof) { 6764 PetscInt *rStar = NULL, rStarSize; 6765 6766 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6767 for (v = 0; v < rStarSize*2; v += 2) { 6768 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 6769 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 6770 6771 rc = rStar[v]; 6772 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 6773 if (!rcdof) continue; 6774 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 6775 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6776 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 6777 if (cone[p] == newv) { 6778 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 6779 break; 6780 } 6781 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 6782 } 6783 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6784 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6785 } 6786 } 6787 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6788 } 6789 } 6790 case REFINER_SIMPLEX_2D: 6791 case REFINER_HYBRID_SIMPLEX_2D: 6792 case REFINER_SIMPLEX_3D: 6793 case REFINER_HYBRID_SIMPLEX_3D: 6794 /* Edge vertices have the average of endpoint coordinates */ 6795 for (e = eStart; e < eMax; ++e) { 6796 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6797 const PetscInt *cone; 6798 PetscInt coneSize, offA, offB, offnew, d; 6799 6800 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 6801 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 6802 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6803 if (localize) { 6804 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 6805 PetscInt *eStar = NULL, eStarSize; 6806 PetscInt *rStar = NULL, rStarSize; 6807 PetscBool cellfound = PETSC_FALSE; 6808 6809 offA = offB = -1; 6810 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 6811 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 6812 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 6813 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6814 for (v = 0; v < eStarSize*2; v += 2) { 6815 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 6816 PetscScalar coordsNewAux[3]; 6817 PetscInt *cellCone = NULL; 6818 PetscInt cellClosureSize, s, cv, cdof; 6819 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 6820 const PetscInt cell = eStar[v]; 6821 6822 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 6823 if (!cdof) { 6824 /* Found a valid edge for the "vertex" part of the Section */ 6825 offA = voffA; 6826 offB = voffB; 6827 cellfound = PETSC_TRUE; 6828 } else { 6829 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 6830 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6831 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 6832 const PetscInt point = cellCone[s]; 6833 if ((point >= vStart) && (point < vEnd)) { 6834 if (point == cone[0]) toffA = spaceDim*cv + coff; 6835 else if (point == cone[1]) toffB = spaceDim*cv + coff; 6836 cv++; 6837 } 6838 } 6839 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6840 for (d = 0; d < spaceDim; ++d) { 6841 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 6842 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 6843 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 6844 } 6845 /* Found a valid edge for the "vertex" part of the Section */ 6846 if (!cellfound && (locvA || locvB)) { 6847 cellfound = PETSC_TRUE; 6848 offA = toffA; 6849 offB = toffB; 6850 } 6851 } 6852 6853 /* Localize new coordinates on each refined cell */ 6854 for (s = 0; s < rStarSize*2; s += 2) { 6855 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 6856 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 6857 const PetscInt rcell = rStar[s]; 6858 6859 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 6860 if (!rcdof) continue; 6861 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 6862 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6863 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 6864 if (rcone[p] == newv) { 6865 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 6866 break; 6867 } 6868 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 6869 } 6870 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6871 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6872 } 6873 } 6874 } 6875 } 6876 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 6877 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6878 if (!cellfound) { 6879 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 6880 needcoords = PETSC_TRUE; 6881 } 6882 } else { 6883 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 6884 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 6885 } 6886 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6887 if (offA != -1 && offB != -1) { 6888 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 6889 for (d = 0; d < spaceDim; ++d) { 6890 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 6891 } 6892 } else { 6893 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 6894 } 6895 } 6896 /* Old vertices have the same coordinates */ 6897 for (v = vStart; v < vEnd; ++v) { 6898 const PetscInt newv = vStartNew + (v - vStart); 6899 PetscInt off, offnew, d; 6900 6901 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 6902 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6903 for (d = 0; d < spaceDim; ++d) { 6904 coordsNew[offnew+d] = coords[off+d]; 6905 } 6906 6907 /* Localize new coordinates on each refined cell */ 6908 if (localize) { 6909 PetscInt p; 6910 PetscInt *rStar = NULL, rStarSize; 6911 6912 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6913 for (p = 0; p < rStarSize*2; p += 2) { 6914 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 6915 PetscScalar ocoords[3]; 6916 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 6917 6918 c = rStar[p]; 6919 oc = parentId[c-cStartNew]; 6920 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 6921 if (!cdof) continue; 6922 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 6923 if (!cdof) continue; 6924 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 6925 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6926 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 6927 if (cone[s] == v) { 6928 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 6929 break; 6930 } 6931 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 6932 } 6933 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D\n",v); 6934 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6935 6936 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 6937 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6938 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 6939 if (cone[s] == newv) { 6940 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 6941 break; 6942 } 6943 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 6944 } 6945 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6946 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6947 } 6948 } 6949 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6950 } 6951 } 6952 break; 6953 default: 6954 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6955 } 6956 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 6957 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 6958 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 6959 6960 /* Final reduction (if needed) if we are localizing */ 6961 if (localize) { 6962 PetscBool gred; 6963 6964 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 6965 if (gred) { 6966 DM cdm; 6967 Vec aux; 6968 PetscSF sf; 6969 const PetscScalar *lArray; 6970 PetscScalar *gArray; 6971 6972 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 6973 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 6974 ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr); 6975 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 6976 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 6977 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 6978 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 6979 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 6980 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 6981 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 6982 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 6983 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 6984 ierr = VecDestroy(&aux);CHKERRQ(ierr); 6985 } 6986 } 6987 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 6988 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 6989 ierr = PetscFree(parentId);CHKERRQ(ierr); 6990 PetscFunctionReturn(0); 6991 } 6992 6993 /*@ 6994 DMPlexCreateProcessSF - Create an SF which just has process connectivity 6995 6996 Collective on DM 6997 6998 Input Parameters: 6999 + dm - The DM 7000 - sfPoint - The PetscSF which encodes point connectivity 7001 7002 Output Parameters: 7003 + processRanks - A list of process neighbors, or NULL 7004 - sfProcess - An SF encoding the process connectivity, or NULL 7005 7006 Level: developer 7007 7008 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 7009 @*/ 7010 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 7011 { 7012 PetscInt numRoots, numLeaves, l; 7013 const PetscInt *localPoints; 7014 const PetscSFNode *remotePoints; 7015 PetscInt *localPointsNew; 7016 PetscSFNode *remotePointsNew; 7017 PetscInt *ranks, *ranksNew; 7018 PetscMPIInt size; 7019 PetscErrorCode ierr; 7020 7021 PetscFunctionBegin; 7022 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7023 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 7024 if (processRanks) {PetscValidPointer(processRanks, 3);} 7025 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 7026 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 7027 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 7028 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 7029 for (l = 0; l < numLeaves; ++l) { 7030 ranks[l] = remotePoints[l].rank; 7031 } 7032 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 7033 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 7034 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 7035 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 7036 for (l = 0; l < numLeaves; ++l) { 7037 ranksNew[l] = ranks[l]; 7038 localPointsNew[l] = l; 7039 remotePointsNew[l].index = 0; 7040 remotePointsNew[l].rank = ranksNew[l]; 7041 } 7042 ierr = PetscFree(ranks);CHKERRQ(ierr); 7043 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 7044 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 7045 if (sfProcess) { 7046 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 7047 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 7048 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 7049 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 7050 } 7051 PetscFunctionReturn(0); 7052 } 7053 7054 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 7055 { 7056 PetscSF sf, sfNew, sfProcess; 7057 IS processRanks; 7058 MPI_Datatype depthType; 7059 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 7060 const PetscInt *localPoints, *neighbors; 7061 const PetscSFNode *remotePoints; 7062 PetscInt *localPointsNew; 7063 PetscSFNode *remotePointsNew; 7064 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 7065 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 7066 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7067 PetscErrorCode ierr; 7068 7069 PetscFunctionBegin; 7070 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 7071 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 7072 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 7073 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth); 7074 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7075 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 7076 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7077 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7078 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7079 cMax = cMax < 0 ? cEnd : cMax; 7080 fMax = fMax < 0 ? fEnd : fMax; 7081 eMax = eMax < 0 ? eEnd : eMax; 7082 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7083 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 7084 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 7085 /* Calculate size of new SF */ 7086 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 7087 if (numRoots < 0) PetscFunctionReturn(0); 7088 for (l = 0; l < numLeaves; ++l) { 7089 const PetscInt p = localPoints[l]; 7090 7091 switch (refiner) { 7092 case REFINER_SIMPLEX_1D: 7093 if ((p >= vStart) && (p < vEnd)) { 7094 /* Interior vertices stay the same */ 7095 ++numLeavesNew; 7096 } else if ((p >= cStart && p < cMax)) { 7097 /* Interior cells add new cells and interior vertices */ 7098 numLeavesNew += 2 + 1; 7099 } 7100 break; 7101 case REFINER_SIMPLEX_2D: 7102 case REFINER_HYBRID_SIMPLEX_2D: 7103 if ((p >= vStart) && (p < vEnd)) { 7104 /* Interior vertices stay the same */ 7105 ++numLeavesNew; 7106 } else if ((p >= fStart) && (p < fMax)) { 7107 /* Interior faces add new faces and vertex */ 7108 numLeavesNew += 2 + 1; 7109 } else if ((p >= fMax) && (p < fEnd)) { 7110 /* Hybrid faces stay the same */ 7111 ++numLeavesNew; 7112 } else if ((p >= cStart) && (p < cMax)) { 7113 /* Interior cells add new cells and interior faces */ 7114 numLeavesNew += 4 + 3; 7115 } else if ((p >= cMax) && (p < cEnd)) { 7116 /* Hybrid cells add new cells and hybrid face */ 7117 numLeavesNew += 2 + 1; 7118 } 7119 break; 7120 case REFINER_SIMPLEX_TO_HEX_2D: 7121 if ((p >= vStart) && (p < vEnd)) { 7122 /* Interior vertices stay the same */ 7123 ++numLeavesNew; 7124 } else if ((p >= fStart) && (p < fEnd)) { 7125 /* Interior faces add new faces and vertex */ 7126 numLeavesNew += 2 + 1; 7127 } else if ((p >= cStart) && (p < cEnd)) { 7128 /* Interior cells add new cells, interior faces, and vertex */ 7129 numLeavesNew += 3 + 3 + 1; 7130 } 7131 break; 7132 case REFINER_HEX_2D: 7133 case REFINER_HYBRID_HEX_2D: 7134 if ((p >= vStart) && (p < vEnd)) { 7135 /* Interior vertices stay the same */ 7136 ++numLeavesNew; 7137 } else if ((p >= fStart) && (p < fMax)) { 7138 /* Interior faces add new faces and vertex */ 7139 numLeavesNew += 2 + 1; 7140 } else if ((p >= fMax) && (p < fEnd)) { 7141 /* Hybrid faces stay the same */ 7142 ++numLeavesNew; 7143 } else if ((p >= cStart) && (p < cMax)) { 7144 /* Interior cells add new cells, interior faces, and vertex */ 7145 numLeavesNew += 4 + 4 + 1; 7146 } else if ((p >= cMax) && (p < cEnd)) { 7147 /* Hybrid cells add new cells and hybrid face */ 7148 numLeavesNew += 2 + 1; 7149 } 7150 break; 7151 case REFINER_SIMPLEX_3D: 7152 case REFINER_HYBRID_SIMPLEX_3D: 7153 if ((p >= vStart) && (p < vEnd)) { 7154 /* Interior vertices stay the same */ 7155 ++numLeavesNew; 7156 } else if ((p >= eStart) && (p < eMax)) { 7157 /* Interior edges add new edges and vertex */ 7158 numLeavesNew += 2 + 1; 7159 } else if ((p >= eMax) && (p < eEnd)) { 7160 /* Hybrid edges stay the same */ 7161 ++numLeavesNew; 7162 } else if ((p >= fStart) && (p < fMax)) { 7163 /* Interior faces add new faces and edges */ 7164 numLeavesNew += 4 + 3; 7165 } else if ((p >= fMax) && (p < fEnd)) { 7166 /* Hybrid faces add new faces and edges */ 7167 numLeavesNew += 2 + 1; 7168 } else if ((p >= cStart) && (p < cMax)) { 7169 /* Interior cells add new cells, faces, and edges */ 7170 numLeavesNew += 8 + 8 + 1; 7171 } else if ((p >= cMax) && (p < cEnd)) { 7172 /* Hybrid cells add new cells and faces */ 7173 numLeavesNew += 4 + 3; 7174 } 7175 break; 7176 case REFINER_SIMPLEX_TO_HEX_3D: 7177 if ((p >= vStart) && (p < vEnd)) { 7178 /* Interior vertices stay the same */ 7179 ++numLeavesNew; 7180 } else if ((p >= eStart) && (p < eEnd)) { 7181 /* Interior edges add new edges and vertex */ 7182 numLeavesNew += 2 + 1; 7183 } else if ((p >= fStart) && (p < fEnd)) { 7184 /* Interior faces add new faces, edges and a vertex */ 7185 numLeavesNew += 3 + 3 + 1; 7186 } else if ((p >= cStart) && (p < cEnd)) { 7187 /* Interior cells add new cells, faces, edges and a vertex */ 7188 numLeavesNew += 4 + 6 + 4 + 1; 7189 } 7190 break; 7191 case REFINER_HEX_3D: 7192 case REFINER_HYBRID_HEX_3D: 7193 if ((p >= vStart) && (p < vEnd)) { 7194 /* Old vertices stay the same */ 7195 ++numLeavesNew; 7196 } else if ((p >= eStart) && (p < eMax)) { 7197 /* Interior edges add new edges, and vertex */ 7198 numLeavesNew += 2 + 1; 7199 } else if ((p >= eMax) && (p < eEnd)) { 7200 /* Hybrid edges stay the same */ 7201 ++numLeavesNew; 7202 } else if ((p >= fStart) && (p < fMax)) { 7203 /* Interior faces add new faces, edges, and vertex */ 7204 numLeavesNew += 4 + 4 + 1; 7205 } else if ((p >= fMax) && (p < fEnd)) { 7206 /* Hybrid faces add new faces and edges */ 7207 numLeavesNew += 2 + 1; 7208 } else if ((p >= cStart) && (p < cMax)) { 7209 /* Interior cells add new cells, faces, edges, and vertex */ 7210 numLeavesNew += 8 + 12 + 6 + 1; 7211 } else if ((p >= cStart) && (p < cEnd)) { 7212 /* Hybrid cells add new cells, faces, and edges */ 7213 numLeavesNew += 4 + 4 + 1; 7214 } 7215 break; 7216 default: 7217 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7218 } 7219 } 7220 /* Communicate depthSizes for each remote rank */ 7221 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 7222 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 7223 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 7224 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 7225 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 7226 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 7227 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 7228 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 7229 for (n = 0; n < numNeighbors; ++n) { 7230 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 7231 } 7232 depthSizeOld[depth] = cMax; 7233 depthSizeOld[0] = vMax; 7234 depthSizeOld[depth-1] = fMax; 7235 depthSizeOld[1] = eMax; 7236 7237 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 7238 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 7239 7240 depthSizeOld[depth] = cEnd - cStart; 7241 depthSizeOld[0] = vEnd - vStart; 7242 depthSizeOld[depth-1] = fEnd - fStart; 7243 depthSizeOld[1] = eEnd - eStart; 7244 7245 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 7246 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 7247 for (n = 0; n < numNeighbors; ++n) { 7248 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 7249 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 7250 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]; 7251 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 7252 } 7253 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 7254 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 7255 /* Calculate new point SF */ 7256 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 7257 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 7258 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 7259 for (l = 0, m = 0; l < numLeaves; ++l) { 7260 PetscInt p = localPoints[l]; 7261 PetscInt rp = remotePoints[l].index, n; 7262 PetscMPIInt rrank = remotePoints[l].rank; 7263 7264 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 7265 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 7266 switch (refiner) { 7267 case REFINER_SIMPLEX_1D: 7268 if ((p >= vStart) && (p < vEnd)) { 7269 /* Old vertices stay the same */ 7270 localPointsNew[m] = vStartNew + (p - vStart); 7271 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7272 remotePointsNew[m].rank = rrank; 7273 ++m; 7274 } else if ((p >= cStart) && (p < cMax)) { 7275 /* Old interior cells add new cells and vertex */ 7276 for (r = 0; r < 2; ++r, ++m) { 7277 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 7278 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 7279 remotePointsNew[m].rank = rrank; 7280 } 7281 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 7282 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 7283 remotePointsNew[m].rank = rrank; 7284 ++m; 7285 } 7286 break; 7287 case REFINER_SIMPLEX_2D: 7288 case REFINER_HYBRID_SIMPLEX_2D: 7289 if ((p >= vStart) && (p < vEnd)) { 7290 /* Old vertices stay the same */ 7291 localPointsNew[m] = vStartNew + (p - vStart); 7292 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7293 remotePointsNew[m].rank = rrank; 7294 ++m; 7295 } else if ((p >= fStart) && (p < fMax)) { 7296 /* Old interior faces add new faces and vertex */ 7297 for (r = 0; r < 2; ++r, ++m) { 7298 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7299 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7300 remotePointsNew[m].rank = rrank; 7301 } 7302 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7303 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7304 remotePointsNew[m].rank = rrank; 7305 ++m; 7306 } else if ((p >= fMax) && (p < fEnd)) { 7307 /* Old hybrid faces stay the same */ 7308 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 7309 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 7310 remotePointsNew[m].rank = rrank; 7311 ++m; 7312 } else if ((p >= cStart) && (p < cMax)) { 7313 /* Old interior cells add new cells and interior faces */ 7314 for (r = 0; r < 4; ++r, ++m) { 7315 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7316 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7317 remotePointsNew[m].rank = rrank; 7318 } 7319 for (r = 0; r < 3; ++r, ++m) { 7320 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 7321 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 7322 remotePointsNew[m].rank = rrank; 7323 } 7324 } else if ((p >= cMax) && (p < cEnd)) { 7325 /* Old hybrid cells add new cells and hybrid face */ 7326 for (r = 0; r < 2; ++r, ++m) { 7327 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7328 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7329 remotePointsNew[m].rank = rrank; 7330 } 7331 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 7332 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]); 7333 remotePointsNew[m].rank = rrank; 7334 ++m; 7335 } 7336 break; 7337 case REFINER_SIMPLEX_TO_HEX_2D: 7338 if ((p >= vStart) && (p < vEnd)) { 7339 /* Old vertices stay the same */ 7340 localPointsNew[m] = vStartNew + (p - vStart); 7341 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7342 remotePointsNew[m].rank = rrank; 7343 ++m; 7344 } else if ((p >= fStart) && (p < fEnd)) { 7345 /* Old interior faces add new faces and vertex */ 7346 for (r = 0; r < 2; ++r, ++m) { 7347 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7348 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7349 remotePointsNew[m].rank = rrank; 7350 } 7351 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7352 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7353 remotePointsNew[m].rank = rrank; 7354 ++m; 7355 } else if ((p >= cStart) && (p < cEnd)) { 7356 /* Old interior cells add new cells, interior faces, and a vertex */ 7357 for (r = 0; r < 3; ++r, ++m) { 7358 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 7359 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 7360 remotePointsNew[m].rank = rrank; 7361 } 7362 for (r = 0; r < 3; ++r, ++m) { 7363 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7364 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 7365 remotePointsNew[m].rank = rrank; 7366 } 7367 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7368 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 7369 remotePointsNew[m].rank = rrank; 7370 ++m; 7371 } 7372 break; 7373 case REFINER_HEX_2D: 7374 case REFINER_HYBRID_HEX_2D: 7375 if ((p >= vStart) && (p < vEnd)) { 7376 /* Old vertices stay the same */ 7377 localPointsNew[m] = vStartNew + (p - vStart); 7378 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7379 remotePointsNew[m].rank = rrank; 7380 ++m; 7381 } else if ((p >= fStart) && (p < fMax)) { 7382 /* Old interior faces add new faces and vertex */ 7383 for (r = 0; r < 2; ++r, ++m) { 7384 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7385 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7386 remotePointsNew[m].rank = rrank; 7387 } 7388 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7389 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7390 remotePointsNew[m].rank = rrank; 7391 ++m; 7392 } else if ((p >= fMax) && (p < fEnd)) { 7393 /* Old hybrid faces stay the same */ 7394 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 7395 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 7396 remotePointsNew[m].rank = rrank; 7397 ++m; 7398 } else if ((p >= cStart) && (p < cMax)) { 7399 /* Old interior cells add new cells, interior faces, and vertex */ 7400 for (r = 0; r < 4; ++r, ++m) { 7401 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7402 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7403 remotePointsNew[m].rank = rrank; 7404 } 7405 for (r = 0; r < 4; ++r, ++m) { 7406 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 7407 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 7408 remotePointsNew[m].rank = rrank; 7409 } 7410 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 7411 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 7412 remotePointsNew[m].rank = rrank; 7413 ++m; 7414 } else if ((p >= cStart) && (p < cMax)) { 7415 /* Old hybrid cells add new cells and hybrid face */ 7416 for (r = 0; r < 2; ++r, ++m) { 7417 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7418 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7419 remotePointsNew[m].rank = rrank; 7420 } 7421 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 7422 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]); 7423 remotePointsNew[m].rank = rrank; 7424 ++m; 7425 } 7426 break; 7427 case REFINER_SIMPLEX_3D: 7428 case REFINER_HYBRID_SIMPLEX_3D: 7429 if ((p >= vStart) && (p < vEnd)) { 7430 /* Interior vertices stay the same */ 7431 localPointsNew[m] = vStartNew + (p - vStart); 7432 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7433 remotePointsNew[m].rank = rrank; 7434 ++m; 7435 } else if ((p >= eStart) && (p < eMax)) { 7436 /* Interior edges add new edges and vertex */ 7437 for (r = 0; r < 2; ++r, ++m) { 7438 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7439 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7440 remotePointsNew[m].rank = rrank; 7441 } 7442 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7443 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7444 remotePointsNew[m].rank = rrank; 7445 ++m; 7446 } else if ((p >= eMax) && (p < eEnd)) { 7447 /* Hybrid edges stay the same */ 7448 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 7449 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]); 7450 remotePointsNew[m].rank = rrank; 7451 ++m; 7452 } else if ((p >= fStart) && (p < fMax)) { 7453 /* Interior faces add new faces and edges */ 7454 for (r = 0; r < 4; ++r, ++m) { 7455 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7456 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7457 remotePointsNew[m].rank = rrank; 7458 } 7459 for (r = 0; r < 3; ++r, ++m) { 7460 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 7461 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 7462 remotePointsNew[m].rank = rrank; 7463 } 7464 } else if ((p >= fMax) && (p < fEnd)) { 7465 /* Hybrid faces add new faces and edges */ 7466 for (r = 0; r < 2; ++r, ++m) { 7467 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 7468 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; 7469 remotePointsNew[m].rank = rrank; 7470 } 7471 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 7472 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]); 7473 remotePointsNew[m].rank = rrank; 7474 ++m; 7475 } else if ((p >= cStart) && (p < cMax)) { 7476 /* Interior cells add new cells, faces, and edges */ 7477 for (r = 0; r < 8; ++r, ++m) { 7478 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7479 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7480 remotePointsNew[m].rank = rrank; 7481 } 7482 for (r = 0; r < 8; ++r, ++m) { 7483 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 7484 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 7485 remotePointsNew[m].rank = rrank; 7486 } 7487 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 7488 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; 7489 remotePointsNew[m].rank = rrank; 7490 ++m; 7491 } else if ((p >= cMax) && (p < cEnd)) { 7492 /* Hybrid cells add new cells and faces */ 7493 for (r = 0; r < 4; ++r, ++m) { 7494 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7495 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7496 remotePointsNew[m].rank = rrank; 7497 } 7498 for (r = 0; r < 3; ++r, ++m) { 7499 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 7500 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; 7501 remotePointsNew[m].rank = rrank; 7502 } 7503 } 7504 break; 7505 case REFINER_SIMPLEX_TO_HEX_3D: 7506 if ((p >= vStart) && (p < vEnd)) { 7507 /* Interior vertices stay the same */ 7508 localPointsNew[m] = vStartNew + (p - vStart); 7509 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7510 remotePointsNew[m].rank = rrank; 7511 ++m; 7512 } else if ((p >= eStart) && (p < eEnd)) { 7513 /* Interior edges add new edges and vertex */ 7514 for (r = 0; r < 2; ++r, ++m) { 7515 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7516 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7517 remotePointsNew[m].rank = rrank; 7518 } 7519 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7520 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7521 remotePointsNew[m].rank = rrank; 7522 ++m; 7523 } else if ((p >= fStart) && (p < fEnd)) { 7524 /* Interior faces add new faces, edges and a vertex */ 7525 for (r = 0; r < 3; ++r, ++m) { 7526 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 7527 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 7528 remotePointsNew[m].rank = rrank; 7529 } 7530 for (r = 0; r < 3; ++r, ++m) { 7531 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 7532 remotePointsNew[m].index = reStartNew[n] + (rdepthSizeOld[n*(depth+1)+1])*2 + (rp - rfStart[n])*3 + r; 7533 remotePointsNew[m].rank = rrank; 7534 } 7535 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 7536 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 7537 remotePointsNew[m].rank = rrank; 7538 ++m; 7539 } else if ((p >= cStart) && (p < cEnd)) { 7540 /* Interior cells add new cells, faces, edges, and a vertex */ 7541 for (r = 0; r < 4; ++r, ++m) { 7542 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7543 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7544 remotePointsNew[m].rank = rrank; 7545 } 7546 for (r = 0; r < 6; ++r, ++m) { 7547 localPointsNew[m] = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 7548 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*6 + r; 7549 remotePointsNew[m].rank = rrank; 7550 } 7551 for (r = 0; r < 4; ++r, ++m) { 7552 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 7553 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*4 + r; 7554 remotePointsNew[m].rank = rrank; 7555 } 7556 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 7557 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 7558 remotePointsNew[m].rank = rrank; 7559 ++m; 7560 } 7561 break; 7562 case REFINER_HEX_3D: 7563 case REFINER_HYBRID_HEX_3D: 7564 if ((p >= vStart) && (p < vEnd)) { 7565 /* Interior vertices stay the same */ 7566 localPointsNew[m] = vStartNew + (p - vStart); 7567 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7568 remotePointsNew[m].rank = rrank; 7569 ++m; 7570 } else if ((p >= eStart) && (p < eMax)) { 7571 /* Interior edges add new edges and vertex */ 7572 for (r = 0; r < 2; ++r, ++m) { 7573 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7574 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7575 remotePointsNew[m].rank = rrank; 7576 } 7577 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7578 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7579 remotePointsNew[m].rank = rrank; 7580 ++m; 7581 } else if ((p >= eMax) && (p < eEnd)) { 7582 /* Hybrid edges stay the same */ 7583 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 7584 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]); 7585 remotePointsNew[m].rank = rrank; 7586 ++m; 7587 } else if ((p >= fStart) && (p < fMax)) { 7588 /* Interior faces add new faces, edges, and vertex */ 7589 for (r = 0; r < 4; ++r, ++m) { 7590 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7591 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7592 remotePointsNew[m].rank = rrank; 7593 } 7594 for (r = 0; r < 4; ++r, ++m) { 7595 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 7596 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 7597 remotePointsNew[m].rank = rrank; 7598 } 7599 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 7600 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 7601 remotePointsNew[m].rank = rrank; 7602 ++m; 7603 } else if ((p >= fMax) && (p < fEnd)) { 7604 /* Hybrid faces add new faces and edges */ 7605 for (r = 0; r < 2; ++r, ++m) { 7606 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 7607 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; 7608 remotePointsNew[m].rank = rrank; 7609 } 7610 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 7611 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]); 7612 remotePointsNew[m].rank = rrank; 7613 ++m; 7614 } else if ((p >= cStart) && (p < cMax)) { 7615 /* Interior cells add new cells, faces, edges, and vertex */ 7616 for (r = 0; r < 8; ++r, ++m) { 7617 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7618 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7619 remotePointsNew[m].rank = rrank; 7620 } 7621 for (r = 0; r < 12; ++r, ++m) { 7622 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 7623 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 7624 remotePointsNew[m].rank = rrank; 7625 } 7626 for (r = 0; r < 6; ++r, ++m) { 7627 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 7628 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; 7629 remotePointsNew[m].rank = rrank; 7630 } 7631 for (r = 0; r < 1; ++r, ++m) { 7632 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 7633 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 7634 remotePointsNew[m].rank = rrank; 7635 } 7636 } else if ((p >= cMax) && (p < cEnd)) { 7637 /* Hybrid cells add new cells, faces, and edges */ 7638 for (r = 0; r < 4; ++r, ++m) { 7639 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7640 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7641 remotePointsNew[m].rank = rrank; 7642 } 7643 for (r = 0; r < 4; ++r, ++m) { 7644 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 7645 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; 7646 remotePointsNew[m].rank = rrank; 7647 } 7648 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 7649 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]); 7650 remotePointsNew[m].rank = rrank; 7651 ++m; 7652 } 7653 break; 7654 default: 7655 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7656 } 7657 } 7658 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 7659 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 7660 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 7661 { 7662 PetscSFNode *rp, *rtmp; 7663 PetscInt *lp, *idx, *ltmp, i; 7664 7665 /* SF needs sorted leaves to correct calculate Gather */ 7666 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 7667 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 7668 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 7669 for (i = 0; i < numLeavesNew; ++i) { 7670 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); 7671 idx[i] = i; 7672 } 7673 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 7674 for (i = 0; i < numLeavesNew; ++i) { 7675 lp[i] = localPointsNew[idx[i]]; 7676 rp[i] = remotePointsNew[idx[i]]; 7677 } 7678 ltmp = localPointsNew; 7679 localPointsNew = lp; 7680 rtmp = remotePointsNew; 7681 remotePointsNew = rp; 7682 ierr = PetscFree(idx);CHKERRQ(ierr); 7683 ierr = PetscFree(ltmp);CHKERRQ(ierr); 7684 ierr = PetscFree(rtmp);CHKERRQ(ierr); 7685 } 7686 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 7687 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 7688 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 7689 PetscFunctionReturn(0); 7690 } 7691 7692 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 7693 { 7694 PetscInt numLabels, l; 7695 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 7696 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7697 PetscErrorCode ierr; 7698 7699 PetscFunctionBegin; 7700 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7701 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 7702 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7703 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7704 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 7705 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7706 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 7707 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7708 switch (refiner) { 7709 case REFINER_NOOP: 7710 case REFINER_SIMPLEX_1D: 7711 case REFINER_SIMPLEX_2D: 7712 case REFINER_SIMPLEX_TO_HEX_2D: 7713 case REFINER_HEX_2D: 7714 case REFINER_SIMPLEX_3D: 7715 case REFINER_HEX_3D: 7716 case REFINER_SIMPLEX_TO_HEX_3D: 7717 break; 7718 case REFINER_HYBRID_SIMPLEX_3D: 7719 case REFINER_HYBRID_HEX_3D: 7720 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 7721 case REFINER_HYBRID_SIMPLEX_2D: 7722 case REFINER_HYBRID_HEX_2D: 7723 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 7724 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 7725 break; 7726 default: 7727 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7728 } 7729 for (l = 0; l < numLabels; ++l) { 7730 DMLabel label, labelNew; 7731 const char *lname; 7732 PetscBool isDepth; 7733 IS valueIS; 7734 const PetscInt *values; 7735 PetscInt defVal; 7736 PetscInt numValues, val; 7737 7738 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 7739 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 7740 if (isDepth) continue; 7741 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 7742 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 7743 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 7744 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 7745 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 7746 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 7747 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 7748 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 7749 for (val = 0; val < numValues; ++val) { 7750 IS pointIS; 7751 const PetscInt *points; 7752 PetscInt numPoints, n; 7753 7754 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 7755 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 7756 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 7757 /* Ensure refined label is created with same number of strata as 7758 * original (even if no entries here). */ 7759 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 7760 for (n = 0; n < numPoints; ++n) { 7761 const PetscInt p = points[n]; 7762 switch (refiner) { 7763 case REFINER_SIMPLEX_1D: 7764 if ((p >= vStart) && (p < vEnd)) { 7765 /* Old vertices stay the same */ 7766 newp = vStartNew + (p - vStart); 7767 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7768 } else if ((p >= cStart) && (p < cEnd)) { 7769 /* Old cells add new cells and vertex */ 7770 newp = vStartNew + (vEnd - vStart) + (p - cStart); 7771 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7772 for (r = 0; r < 2; ++r) { 7773 newp = cStartNew + (p - cStart)*2 + r; 7774 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7775 } 7776 } 7777 break; 7778 case REFINER_SIMPLEX_2D: 7779 if ((p >= vStart) && (p < vEnd)) { 7780 /* Old vertices stay the same */ 7781 newp = vStartNew + (p - vStart); 7782 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7783 } else if ((p >= fStart) && (p < fEnd)) { 7784 /* Old faces add new faces and vertex */ 7785 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7786 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7787 for (r = 0; r < 2; ++r) { 7788 newp = fStartNew + (p - fStart)*2 + r; 7789 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7790 } 7791 } else if ((p >= cStart) && (p < cEnd)) { 7792 /* Old cells add new cells and interior faces */ 7793 for (r = 0; r < 4; ++r) { 7794 newp = cStartNew + (p - cStart)*4 + r; 7795 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7796 } 7797 for (r = 0; r < 3; ++r) { 7798 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7799 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7800 } 7801 } 7802 break; 7803 case REFINER_SIMPLEX_TO_HEX_2D: 7804 if ((p >= vStart) && (p < vEnd)) { 7805 /* Old vertices stay the same */ 7806 newp = vStartNew + (p - vStart); 7807 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7808 } else if ((p >= fStart) && (p < fEnd)) { 7809 /* Old faces add new faces and vertex */ 7810 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7811 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7812 for (r = 0; r < 2; ++r) { 7813 newp = fStartNew + (p - fStart)*2 + r; 7814 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7815 } 7816 } else if ((p >= cStart) && (p < cEnd)) { 7817 /* Old cells add new cells, interior faces, and a vertex */ 7818 for (r = 0; r < 3; ++r) { 7819 newp = cStartNew + (p - cStart)*3 + r; 7820 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7821 } 7822 for (r = 0; r < 3; ++r) { 7823 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7824 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7825 } 7826 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 7827 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7828 } 7829 break; 7830 case REFINER_HEX_2D: 7831 if ((p >= vStart) && (p < vEnd)) { 7832 /* Old vertices stay the same */ 7833 newp = vStartNew + (p - vStart); 7834 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7835 } else if ((p >= fStart) && (p < fEnd)) { 7836 /* Old faces add new faces and vertex */ 7837 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7838 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7839 for (r = 0; r < 2; ++r) { 7840 newp = fStartNew + (p - fStart)*2 + r; 7841 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7842 } 7843 } else if ((p >= cStart) && (p < cEnd)) { 7844 /* Old cells add new cells and interior faces and vertex */ 7845 for (r = 0; r < 4; ++r) { 7846 newp = cStartNew + (p - cStart)*4 + r; 7847 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7848 } 7849 for (r = 0; r < 4; ++r) { 7850 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 7851 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7852 } 7853 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7854 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7855 } 7856 break; 7857 case REFINER_HYBRID_SIMPLEX_2D: 7858 if ((p >= vStart) && (p < vEnd)) { 7859 /* Old vertices stay the same */ 7860 newp = vStartNew + (p - vStart); 7861 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7862 } else if ((p >= fStart) && (p < fMax)) { 7863 /* Old interior faces add new faces and vertex */ 7864 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7865 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7866 for (r = 0; r < 2; ++r) { 7867 newp = fStartNew + (p - fStart)*2 + r; 7868 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7869 } 7870 } else if ((p >= fMax) && (p < fEnd)) { 7871 /* Old hybrid faces stay the same */ 7872 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 7873 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7874 } else if ((p >= cStart) && (p < cMax)) { 7875 /* Old interior cells add new cells and interior faces */ 7876 for (r = 0; r < 4; ++r) { 7877 newp = cStartNew + (p - cStart)*4 + r; 7878 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7879 } 7880 for (r = 0; r < 3; ++r) { 7881 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7882 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7883 } 7884 } else if ((p >= cMax) && (p < cEnd)) { 7885 /* Old hybrid cells add new cells and hybrid face */ 7886 for (r = 0; r < 2; ++r) { 7887 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 7888 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7889 } 7890 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 7891 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7892 } 7893 break; 7894 case REFINER_HYBRID_HEX_2D: 7895 if ((p >= vStart) && (p < vEnd)) { 7896 /* Old vertices stay the same */ 7897 newp = vStartNew + (p - vStart); 7898 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7899 } else if ((p >= fStart) && (p < fMax)) { 7900 /* Old interior faces add new faces and vertex */ 7901 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7902 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7903 for (r = 0; r < 2; ++r) { 7904 newp = fStartNew + (p - fStart)*2 + r; 7905 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7906 } 7907 } else if ((p >= fMax) && (p < fEnd)) { 7908 /* Old hybrid faces stay the same */ 7909 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 7910 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7911 } else if ((p >= cStart) && (p < cMax)) { 7912 /* Old interior cells add new cells, interior faces, and vertex */ 7913 for (r = 0; r < 4; ++r) { 7914 newp = cStartNew + (p - cStart)*4 + r; 7915 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7916 } 7917 for (r = 0; r < 4; ++r) { 7918 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 7919 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7920 } 7921 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7922 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7923 } else if ((p >= cMax) && (p < cEnd)) { 7924 /* Old hybrid cells add new cells and hybrid face */ 7925 for (r = 0; r < 2; ++r) { 7926 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 7927 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7928 } 7929 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 7930 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7931 } 7932 break; 7933 case REFINER_SIMPLEX_3D: 7934 if ((p >= vStart) && (p < vEnd)) { 7935 /* Old vertices stay the same */ 7936 newp = vStartNew + (p - vStart); 7937 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7938 } else if ((p >= eStart) && (p < eEnd)) { 7939 /* Old edges add new edges and vertex */ 7940 for (r = 0; r < 2; ++r) { 7941 newp = eStartNew + (p - eStart)*2 + r; 7942 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7943 } 7944 newp = vStartNew + (vEnd - vStart) + (p - eStart); 7945 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7946 } else if ((p >= fStart) && (p < fEnd)) { 7947 /* Old faces add new faces and edges */ 7948 for (r = 0; r < 4; ++r) { 7949 newp = fStartNew + (p - fStart)*4 + r; 7950 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7951 } 7952 for (r = 0; r < 3; ++r) { 7953 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 7954 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7955 } 7956 } else if ((p >= cStart) && (p < cEnd)) { 7957 /* Old cells add new cells and interior faces and edges */ 7958 for (r = 0; r < 8; ++r) { 7959 newp = cStartNew + (p - cStart)*8 + r; 7960 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7961 } 7962 for (r = 0; r < 8; ++r) { 7963 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 7964 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7965 } 7966 for (r = 0; r < 1; ++r) { 7967 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 7968 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7969 } 7970 } 7971 break; 7972 case REFINER_SIMPLEX_TO_HEX_3D: 7973 if ((p >= vStart) && (p < vEnd)) { 7974 /* Old vertices stay the same */ 7975 newp = vStartNew + (p - vStart); 7976 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7977 } else if ((p >= eStart) && (p < eEnd)) { 7978 /* Old edges add new edges and vertex */ 7979 for (r = 0; r < 2; ++r) { 7980 newp = eStartNew + (p - eStart)*2 + r; 7981 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7982 } 7983 newp = vStartNew + (vEnd - vStart) + (p - eStart); 7984 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7985 } else if ((p >= fStart) && (p < fEnd)) { 7986 /* Old faces add new faces, edges and a vertex */ 7987 for (r = 0; r < 3; ++r) { 7988 newp = fStartNew + (p - fStart)*3 + r; 7989 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7990 } 7991 for (r = 0; r < 3; ++r) { 7992 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 7993 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7994 } 7995 } else if ((p >= cStart) && (p < cEnd)) { 7996 /* Old cells add new cells and interior faces and edges and a vertex */ 7997 for (r = 0; r < 4; ++r) { 7998 newp = cStartNew + (p - cStart)*4 + r; 7999 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8000 } 8001 for (r = 0; r < 6; ++r) { 8002 newp = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 8003 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8004 } 8005 for (r = 0; r < 4; ++r) { 8006 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 8007 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8008 } 8009 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + p - cStart; 8010 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8011 } 8012 break; 8013 case REFINER_HYBRID_SIMPLEX_3D: 8014 if ((p >= vStart) && (p < vEnd)) { 8015 /* Interior vertices stay the same */ 8016 newp = vStartNew + (p - vStart); 8017 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8018 } else if ((p >= eStart) && (p < eMax)) { 8019 /* Interior edges add new edges and vertex */ 8020 for (r = 0; r < 2; ++r) { 8021 newp = eStartNew + (p - eStart)*2 + r; 8022 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8023 } 8024 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8025 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8026 } else if ((p >= eMax) && (p < eEnd)) { 8027 /* Hybrid edges stay the same */ 8028 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 8029 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8030 } else if ((p >= fStart) && (p < fMax)) { 8031 /* Interior faces add new faces and edges */ 8032 for (r = 0; r < 4; ++r) { 8033 newp = fStartNew + (p - fStart)*4 + r; 8034 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8035 } 8036 for (r = 0; r < 3; ++r) { 8037 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 8038 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8039 } 8040 } else if ((p >= fMax) && (p < fEnd)) { 8041 /* Hybrid faces add new faces and edges */ 8042 for (r = 0; r < 2; ++r) { 8043 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 8044 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8045 } 8046 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 8047 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8048 } else if ((p >= cStart) && (p < cMax)) { 8049 /* Interior cells add new cells, faces, and edges */ 8050 for (r = 0; r < 8; ++r) { 8051 newp = cStartNew + (p - cStart)*8 + r; 8052 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8053 } 8054 for (r = 0; r < 8; ++r) { 8055 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 8056 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8057 } 8058 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 8059 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8060 } else if ((p >= cMax) && (p < cEnd)) { 8061 /* Hybrid cells add new cells and faces */ 8062 for (r = 0; r < 4; ++r) { 8063 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 8064 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8065 } 8066 for (r = 0; r < 3; ++r) { 8067 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 8068 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8069 } 8070 } 8071 break; 8072 case REFINER_HEX_3D: 8073 if ((p >= vStart) && (p < vEnd)) { 8074 /* Old vertices stay the same */ 8075 newp = vStartNew + (p - vStart); 8076 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8077 } else if ((p >= eStart) && (p < eEnd)) { 8078 /* Old edges add new edges and vertex */ 8079 for (r = 0; r < 2; ++r) { 8080 newp = eStartNew + (p - eStart)*2 + r; 8081 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8082 } 8083 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8084 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8085 } else if ((p >= fStart) && (p < fEnd)) { 8086 /* Old faces add new faces, edges, and vertex */ 8087 for (r = 0; r < 4; ++r) { 8088 newp = fStartNew + (p - fStart)*4 + r; 8089 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8090 } 8091 for (r = 0; r < 4; ++r) { 8092 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 8093 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8094 } 8095 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 8096 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8097 } else if ((p >= cStart) && (p < cEnd)) { 8098 /* Old cells add new cells, faces, edges, and vertex */ 8099 for (r = 0; r < 8; ++r) { 8100 newp = cStartNew + (p - cStart)*8 + r; 8101 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8102 } 8103 for (r = 0; r < 12; ++r) { 8104 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 8105 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8106 } 8107 for (r = 0; r < 6; ++r) { 8108 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 8109 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8110 } 8111 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 8112 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8113 } 8114 break; 8115 case REFINER_HYBRID_HEX_3D: 8116 if ((p >= vStart) && (p < vEnd)) { 8117 /* Interior vertices stay the same */ 8118 newp = vStartNew + (p - vStart); 8119 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8120 } else if ((p >= eStart) && (p < eMax)) { 8121 /* Interior edges add new edges and vertex */ 8122 for (r = 0; r < 2; ++r) { 8123 newp = eStartNew + (p - eStart)*2 + r; 8124 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8125 } 8126 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8127 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8128 } else if ((p >= eMax) && (p < eEnd)) { 8129 /* Hybrid edges stay the same */ 8130 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 8131 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8132 } else if ((p >= fStart) && (p < fMax)) { 8133 /* Interior faces add new faces, edges, and vertex */ 8134 for (r = 0; r < 4; ++r) { 8135 newp = fStartNew + (p - fStart)*4 + r; 8136 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8137 } 8138 for (r = 0; r < 4; ++r) { 8139 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 8140 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8141 } 8142 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 8143 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8144 } else if ((p >= fMax) && (p < fEnd)) { 8145 /* Hybrid faces add new faces and edges */ 8146 for (r = 0; r < 2; ++r) { 8147 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 8148 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8149 } 8150 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 8151 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8152 } else if ((p >= cStart) && (p < cMax)) { 8153 /* Interior cells add new cells, faces, edges, and vertex */ 8154 for (r = 0; r < 8; ++r) { 8155 newp = cStartNew + (p - cStart)*8 + r; 8156 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8157 } 8158 for (r = 0; r < 12; ++r) { 8159 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 8160 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8161 } 8162 for (r = 0; r < 6; ++r) { 8163 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 8164 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8165 } 8166 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 8167 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8168 } else if ((p >= cMax) && (p < cEnd)) { 8169 /* Hybrid cells add new cells, faces, and edges */ 8170 for (r = 0; r < 4; ++r) { 8171 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 8172 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8173 } 8174 for (r = 0; r < 4; ++r) { 8175 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 8176 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8177 } 8178 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 8179 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8180 } 8181 break; 8182 default: 8183 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 8184 } 8185 } 8186 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 8187 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 8188 } 8189 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 8190 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 8191 if (0) { 8192 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 8193 } 8194 } 8195 PetscFunctionReturn(0); 8196 } 8197 8198 /* This will only work for interpolated meshes */ 8199 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 8200 { 8201 DM rdm; 8202 PetscInt *depthSize; 8203 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 8204 PetscErrorCode ierr; 8205 8206 PetscFunctionBegin; 8207 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 8208 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 8209 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8210 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 8211 /* Calculate number of new points of each depth */ 8212 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8213 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 8214 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 8215 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 8216 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 8217 /* Step 1: Set chart */ 8218 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 8219 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 8220 /* Step 2: Set cone/support sizes */ 8221 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8222 /* Step 3: Setup refined DM */ 8223 ierr = DMSetUp(rdm);CHKERRQ(ierr); 8224 /* Step 4: Set cones and supports */ 8225 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8226 /* Step 5: Stratify */ 8227 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 8228 /* Step 6: Create pointSF */ 8229 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8230 /* Step 7: Create labels */ 8231 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8232 /* Step 8: Set coordinates */ 8233 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8234 ierr = PetscFree(depthSize);CHKERRQ(ierr); 8235 8236 *dmRefined = rdm; 8237 PetscFunctionReturn(0); 8238 } 8239 8240 /*@ 8241 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 8242 8243 Input Parameter: 8244 . dm - The coarse DM 8245 8246 Output Parameter: 8247 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 8248 8249 Level: developer 8250 8251 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 8252 @*/ 8253 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 8254 { 8255 CellRefiner cellRefiner; 8256 PetscInt *depthSize, *fpoints; 8257 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8258 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 8259 PetscErrorCode ierr; 8260 8261 PetscFunctionBegin; 8262 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8263 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 8264 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8265 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 8266 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 8267 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 8268 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8269 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 8270 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 8271 switch (cellRefiner) { 8272 case REFINER_SIMPLEX_1D: 8273 case REFINER_SIMPLEX_2D: 8274 case REFINER_HYBRID_SIMPLEX_2D: 8275 case REFINER_HEX_2D: 8276 case REFINER_HYBRID_HEX_2D: 8277 case REFINER_SIMPLEX_3D: 8278 case REFINER_HYBRID_SIMPLEX_3D: 8279 case REFINER_HEX_3D: 8280 case REFINER_HYBRID_HEX_3D: 8281 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 8282 break; 8283 default: 8284 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 8285 } 8286 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 8287 ierr = PetscFree(depthSize);CHKERRQ(ierr); 8288 PetscFunctionReturn(0); 8289 } 8290 8291 /*@ 8292 DMPlexSetRefinementUniform - Set the flag for uniform refinement 8293 8294 Input Parameters: 8295 + dm - The DM 8296 - refinementUniform - The flag for uniform refinement 8297 8298 Level: developer 8299 8300 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8301 @*/ 8302 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 8303 { 8304 DM_Plex *mesh = (DM_Plex*) dm->data; 8305 8306 PetscFunctionBegin; 8307 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8308 mesh->refinementUniform = refinementUniform; 8309 PetscFunctionReturn(0); 8310 } 8311 8312 /*@ 8313 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 8314 8315 Input Parameter: 8316 . dm - The DM 8317 8318 Output Parameter: 8319 . refinementUniform - The flag for uniform refinement 8320 8321 Level: developer 8322 8323 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8324 @*/ 8325 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 8326 { 8327 DM_Plex *mesh = (DM_Plex*) dm->data; 8328 8329 PetscFunctionBegin; 8330 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8331 PetscValidPointer(refinementUniform, 2); 8332 *refinementUniform = mesh->refinementUniform; 8333 PetscFunctionReturn(0); 8334 } 8335 8336 /*@ 8337 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 8338 8339 Input Parameters: 8340 + dm - The DM 8341 - refinementLimit - The maximum cell volume in the refined mesh 8342 8343 Level: developer 8344 8345 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 8346 @*/ 8347 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 8348 { 8349 DM_Plex *mesh = (DM_Plex*) dm->data; 8350 8351 PetscFunctionBegin; 8352 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8353 mesh->refinementLimit = refinementLimit; 8354 PetscFunctionReturn(0); 8355 } 8356 8357 /*@ 8358 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 8359 8360 Input Parameter: 8361 . dm - The DM 8362 8363 Output Parameter: 8364 . refinementLimit - The maximum cell volume in the refined mesh 8365 8366 Level: developer 8367 8368 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 8369 @*/ 8370 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 8371 { 8372 DM_Plex *mesh = (DM_Plex*) dm->data; 8373 8374 PetscFunctionBegin; 8375 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8376 PetscValidPointer(refinementLimit, 2); 8377 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 8378 *refinementLimit = mesh->refinementLimit; 8379 PetscFunctionReturn(0); 8380 } 8381 8382 /*@ 8383 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 8384 8385 Input Parameters: 8386 + dm - The DM 8387 - refinementFunc - Function giving the maximum cell volume in the refined mesh 8388 8389 Note: The calling sequence is refinementFunc(coords, limit) 8390 $ coords - Coordinates of the current point, usually a cell centroid 8391 $ limit - The maximum cell volume for a cell containing this point 8392 8393 Level: developer 8394 8395 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8396 @*/ 8397 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 8398 { 8399 DM_Plex *mesh = (DM_Plex*) dm->data; 8400 8401 PetscFunctionBegin; 8402 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8403 mesh->refinementFunc = refinementFunc; 8404 PetscFunctionReturn(0); 8405 } 8406 8407 /*@ 8408 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 8409 8410 Input Parameter: 8411 . dm - The DM 8412 8413 Output Parameter: 8414 . refinementFunc - Function giving the maximum cell volume in the refined mesh 8415 8416 Note: The calling sequence is refinementFunc(coords, limit) 8417 $ coords - Coordinates of the current point, usually a cell centroid 8418 $ limit - The maximum cell volume for a cell containing this point 8419 8420 Level: developer 8421 8422 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8423 @*/ 8424 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 8425 { 8426 DM_Plex *mesh = (DM_Plex*) dm->data; 8427 8428 PetscFunctionBegin; 8429 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8430 PetscValidPointer(refinementFunc, 2); 8431 *refinementFunc = mesh->refinementFunc; 8432 PetscFunctionReturn(0); 8433 } 8434 8435 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 8436 { 8437 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 8438 PetscErrorCode ierr; 8439 8440 PetscFunctionBegin; 8441 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8442 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8443 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 8444 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 8445 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 8446 switch (dim) { 8447 case 1: 8448 switch (coneSize) { 8449 case 2: 8450 *cellRefiner = REFINER_SIMPLEX_1D; 8451 break; 8452 default: 8453 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8454 } 8455 break; 8456 case 2: 8457 switch (coneSize) { 8458 case 3: 8459 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 8460 else *cellRefiner = REFINER_SIMPLEX_2D; 8461 break; 8462 case 4: 8463 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 8464 else *cellRefiner = REFINER_HEX_2D; 8465 break; 8466 default: 8467 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8468 } 8469 break; 8470 case 3: 8471 switch (coneSize) { 8472 case 4: 8473 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 8474 else *cellRefiner = REFINER_SIMPLEX_3D; 8475 break; 8476 case 6: 8477 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 8478 else *cellRefiner = REFINER_HEX_3D; 8479 break; 8480 default: 8481 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8482 } 8483 break; 8484 default: 8485 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 8486 } 8487 PetscFunctionReturn(0); 8488 } 8489 8490 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 8491 { 8492 PetscBool isUniform; 8493 PetscErrorCode ierr; 8494 8495 PetscFunctionBegin; 8496 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 8497 if (isUniform) { 8498 CellRefiner cellRefiner; 8499 PetscBool localized; 8500 8501 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 8502 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 8503 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 8504 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 8505 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 8506 } else { 8507 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 8508 } 8509 PetscFunctionReturn(0); 8510 } 8511 8512 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 8513 { 8514 DM cdm = dm; 8515 PetscInt r; 8516 PetscBool isUniform, localized; 8517 PetscErrorCode ierr; 8518 8519 PetscFunctionBegin; 8520 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 8521 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 8522 if (isUniform) { 8523 for (r = 0; r < nlevels; ++r) { 8524 CellRefiner cellRefiner; 8525 8526 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 8527 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 8528 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 8529 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 8530 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 8531 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 8532 cdm = dmRefined[r]; 8533 } 8534 } else { 8535 for (r = 0; r < nlevels; ++r) { 8536 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 8537 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 8538 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 8539 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 8540 cdm = dmRefined[r]; 8541 } 8542 } 8543 PetscFunctionReturn(0); 8544 } 8545