1 #include <petsc-private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2 #include <petscsf.h> 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "GetDepthStart_Private" 6 PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 7 { 8 PetscFunctionBegin; 9 if (cStart) *cStart = 0; 10 if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth]; 11 if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 12 if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 13 PetscFunctionReturn(0); 14 } 15 16 #undef __FUNCT__ 17 #define __FUNCT__ "GetDepthEnd_Private" 18 PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 19 { 20 PetscFunctionBegin; 21 if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth]; 22 if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 23 if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 24 if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 25 PetscFunctionReturn(0); 26 } 27 28 #undef __FUNCT__ 29 #define __FUNCT__ "CellRefinerGetAffineTransforms_Internal" 30 /* Gets the affine map from the original cell to each subcell */ 31 PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 32 { 33 PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ; 34 PetscInt dim, s; 35 PetscErrorCode ierr; 36 37 PetscFunctionBegin; 38 switch (refiner) { 39 case REFINER_NOOP: break; 40 case REFINER_SIMPLEX_2D: 41 /* 42 2 43 |\ 44 | \ 45 | \ 46 | \ 47 | C \ 48 | \ 49 | \ 50 2---1---1 51 |\ D / \ 52 | 2 0 \ 53 |A \ / B \ 54 0---0-------1 55 */ 56 dim = 2; 57 if (numSubcells) *numSubcells = 4; 58 if (v0) { 59 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 60 /* A */ 61 v[0+0] = -1.0; v[0+1] = -1.0; 62 j[0+0] = 0.5; j[0+1] = 0.0; 63 j[0+2] = 0.0; j[0+3] = 0.5; 64 /* B */ 65 v[2+0] = 0.0; v[2+1] = -1.0; 66 j[4+0] = 0.5; j[4+1] = 0.0; 67 j[4+2] = 0.0; j[4+3] = 0.5; 68 /* C */ 69 v[4+0] = -1.0; v[4+1] = 0.0; 70 j[8+0] = 0.5; j[8+1] = 0.0; 71 j[8+2] = 0.0; j[8+3] = 0.5; 72 /* D */ 73 v[6+0] = 0.0; v[6+1] = -1.0; 74 j[12+0] = 0.0; j[12+1] = -0.5; 75 j[12+2] = 0.5; j[12+3] = 0.5; 76 for (s = 0; s < 4; ++s) { 77 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 78 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 79 } 80 } 81 break; 82 case REFINER_HEX_2D: 83 /* 84 3---------2---------2 85 | | | 86 | D 2 C | 87 | | | 88 3----3----0----1----1 89 | | | 90 | A 0 B | 91 | | | 92 0---------0---------1 93 */ 94 dim = 2; 95 if (numSubcells) *numSubcells = 4; 96 if (v0) { 97 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 98 /* A */ 99 v[0+0] = -1.0; v[0+1] = -1.0; 100 j[0+0] = 0.5; j[0+1] = 0.0; 101 j[0+2] = 0.0; j[0+3] = 0.5; 102 /* B */ 103 v[2+0] = 0.0; v[2+1] = -1.0; 104 j[4+0] = 0.5; j[4+1] = 0.0; 105 j[4+2] = 0.0; j[4+3] = 0.5; 106 /* C */ 107 v[4+0] = 0.0; v[4+1] = 0.0; 108 j[8+0] = 0.5; j[8+1] = 0.0; 109 j[8+2] = 0.0; j[8+3] = 0.5; 110 /* D */ 111 v[6+0] = -1.0; v[6+1] = 0.0; 112 j[12+0] = 0.5; j[12+1] = 0.0; 113 j[12+2] = 0.0; j[12+3] = 0.5; 114 for (s = 0; s < 4; ++s) { 115 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 116 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 117 } 118 } 119 break; 120 default: 121 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 122 } 123 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 124 PetscFunctionReturn(0); 125 } 126 127 #undef __FUNCT__ 128 #define __FUNCT__ "CellRefinerRestoreAffineTransforms_Internal" 129 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 130 { 131 PetscErrorCode ierr; 132 133 PetscFunctionBegin; 134 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 135 PetscFunctionReturn(0); 136 } 137 138 #undef __FUNCT__ 139 #define __FUNCT__ "CellRefinerInCellTest_Internal" 140 /* Should this be here or in the DualSpace somehow? */ 141 PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside) 142 { 143 PetscReal sum = 0.0; 144 PetscInt d; 145 146 PetscFunctionBegin; 147 *inside = PETSC_TRUE; 148 switch (refiner) { 149 case REFINER_NOOP: break; 150 case REFINER_SIMPLEX_2D: 151 for (d = 0; d < 2; ++d) { 152 if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 153 sum += point[d]; 154 } 155 if (sum > 0.0) {*inside = PETSC_FALSE; break;} 156 break; 157 case REFINER_HEX_2D: 158 for (d = 0; d < 2; ++d) if ((point[d] < -1.0) || (point[d] > 1.0)) {*inside = PETSC_FALSE; break;} 159 break; 160 default: 161 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 162 } 163 PetscFunctionReturn(0); 164 } 165 166 #undef __FUNCT__ 167 #define __FUNCT__ "CellRefinerGetSizes" 168 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 169 { 170 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 171 PetscErrorCode ierr; 172 173 PetscFunctionBegin; 174 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 175 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 176 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 177 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 178 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 179 switch (refiner) { 180 case REFINER_NOOP: 181 break; 182 case REFINER_SIMPLEX_1D: 183 depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */ 184 depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */ 185 break; 186 case REFINER_SIMPLEX_2D: 187 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 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] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 190 break; 191 case REFINER_HYBRID_SIMPLEX_2D: 192 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 193 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 194 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 195 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 */ 196 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 197 break; 198 case REFINER_HEX_2D: 199 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 200 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 201 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 202 break; 203 case REFINER_HYBRID_HEX_2D: 204 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 205 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 206 /* Quadrilateral */ 207 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 208 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 209 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 210 /* Segment Prisms */ 211 depthSize[0] += 0; /* No hybrid vertices */ 212 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 213 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 214 break; 215 case REFINER_SIMPLEX_3D: 216 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 217 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 */ 218 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 219 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 220 break; 221 case REFINER_HYBRID_SIMPLEX_3D: 222 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 223 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 224 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 225 /* Tetrahedra */ 226 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 227 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 */ 228 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 229 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 230 /* Triangular Prisms */ 231 depthSize[0] += 0; /* No hybrid vertices */ 232 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 233 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 234 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 235 break; 236 case REFINER_HEX_3D: 237 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 238 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 */ 239 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 240 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 241 break; 242 case REFINER_HYBRID_HEX_3D: 243 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 244 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 245 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 246 /* Hexahedra */ 247 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 248 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 */ 249 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 250 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 251 /* Quadrilateral Prisms */ 252 depthSize[0] += 0; /* No hybrid vertices */ 253 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 254 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 255 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 256 break; 257 default: 258 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 259 } 260 PetscFunctionReturn(0); 261 } 262 263 /* Return triangle edge for orientation o, if it is r for o == 0 */ 264 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 265 return (o < 0 ? 2-(o+r) : o+r)%3; 266 } 267 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 268 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 269 } 270 271 /* Return triangle subface for orientation o, if it is r for o == 0 */ 272 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 273 return (o < 0 ? 3-(o+r) : o+r)%3; 274 } 275 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 276 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 277 } 278 279 /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */ 280 PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) { 281 return (o < 0 ? 1-(o+r) : o+r)%3; 282 } 283 PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) { 284 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 285 } 286 287 288 /* Return quad edge for orientation o, if it is r for o == 0 */ 289 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 290 return (o < 0 ? 3-(o+r) : o+r)%4; 291 } 292 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 293 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 294 } 295 296 /* Return quad subface for orientation o, if it is r for o == 0 */ 297 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 298 return (o < 0 ? 4-(o+r) : o+r)%4; 299 } 300 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 301 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 302 } 303 304 #undef __FUNCT__ 305 #define __FUNCT__ "CellRefinerSetConeSizes" 306 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 307 { 308 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 309 PetscErrorCode ierr; 310 311 PetscFunctionBegin; 312 if (!refiner) PetscFunctionReturn(0); 313 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 314 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 315 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 316 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 317 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 318 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 319 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 320 switch (refiner) { 321 case REFINER_SIMPLEX_1D: 322 /* All cells have 2 vertices */ 323 for (c = cStart; c < cEnd; ++c) { 324 for (r = 0; r < 2; ++r) { 325 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 326 327 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 328 } 329 } 330 /* Old vertices have identical supports */ 331 for (v = vStart; v < vEnd; ++v) { 332 const PetscInt newp = vStartNew + (v - vStart); 333 PetscInt size; 334 335 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 336 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 337 } 338 /* Cell vertices have support 2 */ 339 for (c = cStart; c < cEnd; ++c) { 340 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 341 342 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 343 } 344 break; 345 case REFINER_SIMPLEX_2D: 346 /* All cells have 3 faces */ 347 for (c = cStart; c < cEnd; ++c) { 348 for (r = 0; r < 4; ++r) { 349 const PetscInt newp = (c - cStart)*4 + r; 350 351 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 352 } 353 } 354 /* Split faces have 2 vertices and the same cells as the parent */ 355 for (f = fStart; f < fEnd; ++f) { 356 for (r = 0; r < 2; ++r) { 357 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 358 PetscInt size; 359 360 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 361 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 362 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 363 } 364 } 365 /* Interior faces have 2 vertices and 2 cells */ 366 for (c = cStart; c < cEnd; ++c) { 367 for (r = 0; r < 3; ++r) { 368 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 369 370 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 371 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 372 } 373 } 374 /* Old vertices have identical supports */ 375 for (v = vStart; v < vEnd; ++v) { 376 const PetscInt newp = vStartNew + (v - vStart); 377 PetscInt size; 378 379 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 380 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 381 } 382 /* Face vertices have 2 + cells*2 supports */ 383 for (f = fStart; f < fEnd; ++f) { 384 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 385 PetscInt size; 386 387 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 388 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 389 } 390 break; 391 case REFINER_HEX_2D: 392 /* All cells have 4 faces */ 393 for (c = cStart; c < cEnd; ++c) { 394 for (r = 0; r < 4; ++r) { 395 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 396 397 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 398 } 399 } 400 /* Split faces have 2 vertices and the same cells as the parent */ 401 for (f = fStart; f < fEnd; ++f) { 402 for (r = 0; r < 2; ++r) { 403 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 404 PetscInt size; 405 406 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 407 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 408 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 409 } 410 } 411 /* Interior faces have 2 vertices and 2 cells */ 412 for (c = cStart; c < cEnd; ++c) { 413 for (r = 0; r < 4; ++r) { 414 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 415 416 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 417 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 418 } 419 } 420 /* Old vertices have identical supports */ 421 for (v = vStart; v < vEnd; ++v) { 422 const PetscInt newp = vStartNew + (v - vStart); 423 PetscInt size; 424 425 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 426 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 427 } 428 /* Face vertices have 2 + cells supports */ 429 for (f = fStart; f < fEnd; ++f) { 430 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 431 PetscInt size; 432 433 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 434 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 435 } 436 /* Cell vertices have 4 supports */ 437 for (c = cStart; c < cEnd; ++c) { 438 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 439 440 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 441 } 442 break; 443 case REFINER_HYBRID_SIMPLEX_2D: 444 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 445 cMax = PetscMin(cEnd, cMax); 446 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 447 fMax = PetscMin(fEnd, fMax); 448 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 449 /* Interior cells have 3 faces */ 450 for (c = cStart; c < cMax; ++c) { 451 for (r = 0; r < 4; ++r) { 452 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 453 454 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 455 } 456 } 457 /* Hybrid cells have 4 faces */ 458 for (c = cMax; c < cEnd; ++c) { 459 for (r = 0; r < 2; ++r) { 460 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 461 462 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 463 } 464 } 465 /* Interior split faces have 2 vertices and the same cells as the parent */ 466 for (f = fStart; f < fMax; ++f) { 467 for (r = 0; r < 2; ++r) { 468 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 469 PetscInt size; 470 471 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 472 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 473 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 474 } 475 } 476 /* Interior cell faces have 2 vertices and 2 cells */ 477 for (c = cStart; c < cMax; ++c) { 478 for (r = 0; r < 3; ++r) { 479 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 480 481 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 482 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 483 } 484 } 485 /* Hybrid faces have 2 vertices and the same cells */ 486 for (f = fMax; f < fEnd; ++f) { 487 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 488 PetscInt size; 489 490 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 491 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 492 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 493 } 494 /* Hybrid cell faces have 2 vertices and 2 cells */ 495 for (c = cMax; c < cEnd; ++c) { 496 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 497 498 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 499 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 500 } 501 /* Old vertices have identical supports */ 502 for (v = vStart; v < vEnd; ++v) { 503 const PetscInt newp = vStartNew + (v - vStart); 504 PetscInt size; 505 506 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 507 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 508 } 509 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 510 for (f = fStart; f < fMax; ++f) { 511 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 512 const PetscInt *support; 513 PetscInt size, newSize = 2, s; 514 515 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 516 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 517 for (s = 0; s < size; ++s) { 518 if (support[s] >= cMax) newSize += 1; 519 else newSize += 2; 520 } 521 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 522 } 523 break; 524 case REFINER_HYBRID_HEX_2D: 525 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 526 cMax = PetscMin(cEnd, cMax); 527 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 528 fMax = PetscMin(fEnd, fMax); 529 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 530 /* Interior cells have 4 faces */ 531 for (c = cStart; c < cMax; ++c) { 532 for (r = 0; r < 4; ++r) { 533 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 534 535 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 536 } 537 } 538 /* Hybrid cells have 4 faces */ 539 for (c = cMax; c < cEnd; ++c) { 540 for (r = 0; r < 2; ++r) { 541 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 542 543 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 544 } 545 } 546 /* Interior split faces have 2 vertices and the same cells as the parent */ 547 for (f = fStart; f < fMax; ++f) { 548 for (r = 0; r < 2; ++r) { 549 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 550 PetscInt size; 551 552 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 553 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 554 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 555 } 556 } 557 /* Interior cell faces have 2 vertices and 2 cells */ 558 for (c = cStart; c < cMax; ++c) { 559 for (r = 0; r < 4; ++r) { 560 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 561 562 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 563 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 564 } 565 } 566 /* Hybrid faces have 2 vertices and the same cells */ 567 for (f = fMax; f < fEnd; ++f) { 568 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 569 PetscInt size; 570 571 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 572 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 573 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 574 } 575 /* Hybrid cell faces have 2 vertices and 2 cells */ 576 for (c = cMax; c < cEnd; ++c) { 577 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 578 579 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 580 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 581 } 582 /* Old vertices have identical supports */ 583 for (v = vStart; v < vEnd; ++v) { 584 const PetscInt newp = vStartNew + (v - vStart); 585 PetscInt size; 586 587 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 588 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 589 } 590 /* Face vertices have 2 + cells supports */ 591 for (f = fStart; f < fMax; ++f) { 592 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 593 PetscInt size; 594 595 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 596 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 597 } 598 /* Cell vertices have 4 supports */ 599 for (c = cStart; c < cMax; ++c) { 600 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 601 602 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 603 } 604 break; 605 case REFINER_SIMPLEX_3D: 606 /* All cells have 4 faces */ 607 for (c = cStart; c < cEnd; ++c) { 608 for (r = 0; r < 8; ++r) { 609 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 610 611 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 612 } 613 } 614 /* Split faces have 3 edges and the same cells as the parent */ 615 for (f = fStart; f < fEnd; ++f) { 616 for (r = 0; r < 4; ++r) { 617 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 618 PetscInt size; 619 620 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 621 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 622 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 623 } 624 } 625 /* Interior cell faces have 3 edges and 2 cells */ 626 for (c = cStart; c < cEnd; ++c) { 627 for (r = 0; r < 8; ++r) { 628 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 629 630 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 631 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 632 } 633 } 634 /* Split edges have 2 vertices and the same faces */ 635 for (e = eStart; e < eEnd; ++e) { 636 for (r = 0; r < 2; ++r) { 637 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 638 PetscInt size; 639 640 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 641 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 642 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 643 } 644 } 645 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 646 for (f = fStart; f < fEnd; ++f) { 647 for (r = 0; r < 3; ++r) { 648 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 649 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 650 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 651 652 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 653 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 654 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 655 for (s = 0; s < supportSize; ++s) { 656 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 657 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 658 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 659 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 660 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 661 er = GetTetSomethingInverse_Static(ornt[c], r); 662 if (er == eint[c]) { 663 intFaces += 1; 664 } else { 665 intFaces += 2; 666 } 667 } 668 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 669 } 670 } 671 /* Interior cell edges have 2 vertices and 4 faces */ 672 for (c = cStart; c < cEnd; ++c) { 673 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 674 675 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 676 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 677 } 678 /* Old vertices have identical supports */ 679 for (v = vStart; v < vEnd; ++v) { 680 const PetscInt newp = vStartNew + (v - vStart); 681 PetscInt size; 682 683 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 684 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 685 } 686 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 687 for (e = eStart; e < eEnd; ++e) { 688 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 689 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 690 691 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 692 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 693 for (s = 0; s < starSize*2; s += 2) { 694 const PetscInt *cone, *ornt; 695 PetscInt e01, e23; 696 697 if ((star[s] >= cStart) && (star[s] < cEnd)) { 698 /* Check edge 0-1 */ 699 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 700 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 701 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 702 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 703 /* Check edge 2-3 */ 704 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 705 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 706 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 707 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 708 if ((e01 == e) || (e23 == e)) ++cellSize; 709 } 710 } 711 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 712 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 713 } 714 break; 715 case REFINER_HYBRID_SIMPLEX_3D: 716 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 717 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 718 /* Interior cells have 4 faces */ 719 for (c = cStart; c < cMax; ++c) { 720 for (r = 0; r < 8; ++r) { 721 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 722 723 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 724 } 725 } 726 /* Hybrid cells have 5 faces */ 727 for (c = cMax; c < cEnd; ++c) { 728 for (r = 0; r < 4; ++r) { 729 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 730 731 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 732 } 733 } 734 /* Interior split faces have 3 edges and the same cells as the parent */ 735 for (f = fStart; f < fMax; ++f) { 736 for (r = 0; r < 4; ++r) { 737 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 738 PetscInt size; 739 740 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 741 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 742 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 743 } 744 } 745 /* Interior cell faces have 3 edges and 2 cells */ 746 for (c = cStart; c < cMax; ++c) { 747 for (r = 0; r < 8; ++r) { 748 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 749 750 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 751 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 752 } 753 } 754 /* Hybrid split faces have 4 edges and the same cells as the parent */ 755 for (f = fMax; f < fEnd; ++f) { 756 for (r = 0; r < 2; ++r) { 757 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 758 PetscInt size; 759 760 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 761 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 762 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 763 } 764 } 765 /* Hybrid cells faces have 4 edges and 2 cells */ 766 for (c = cMax; c < cEnd; ++c) { 767 for (r = 0; r < 3; ++r) { 768 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 769 770 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 771 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 772 } 773 } 774 /* Interior split edges have 2 vertices and the same faces */ 775 for (e = eStart; e < eMax; ++e) { 776 for (r = 0; r < 2; ++r) { 777 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 778 PetscInt size; 779 780 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 781 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 782 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 783 } 784 } 785 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 786 for (f = fStart; f < fMax; ++f) { 787 for (r = 0; r < 3; ++r) { 788 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 789 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 790 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 791 792 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 793 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 794 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 795 for (s = 0; s < supportSize; ++s) { 796 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 797 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 798 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 799 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 800 if (support[s] < cMax) { 801 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 802 er = GetTetSomethingInverse_Static(ornt[c], r); 803 if (er == eint[c]) { 804 intFaces += 1; 805 } else { 806 intFaces += 2; 807 } 808 } else { 809 intFaces += 1; 810 } 811 } 812 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 813 } 814 } 815 /* Interior cell edges have 2 vertices and 4 faces */ 816 for (c = cStart; c < cMax; ++c) { 817 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 818 819 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 820 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 821 } 822 /* Hybrid edges have 2 vertices and the same faces */ 823 for (e = eMax; e < eEnd; ++e) { 824 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 825 PetscInt size; 826 827 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 828 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 829 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 830 } 831 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 832 for (f = fMax; f < fEnd; ++f) { 833 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 834 PetscInt size; 835 836 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 837 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 838 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 839 } 840 /* Interior vertices have identical supports */ 841 for (v = vStart; v < vEnd; ++v) { 842 const PetscInt newp = vStartNew + (v - vStart); 843 PetscInt size; 844 845 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 846 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 847 } 848 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 849 for (e = eStart; e < eMax; ++e) { 850 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 851 const PetscInt *support; 852 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 853 854 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 855 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 856 for (s = 0; s < size; ++s) { 857 if (support[s] < fMax) faceSize += 2; 858 else faceSize += 1; 859 } 860 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 861 for (s = 0; s < starSize*2; s += 2) { 862 const PetscInt *cone, *ornt; 863 PetscInt e01, e23; 864 865 if ((star[s] >= cStart) && (star[s] < cMax)) { 866 /* Check edge 0-1 */ 867 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 868 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 869 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 870 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 871 /* Check edge 2-3 */ 872 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 873 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 874 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 875 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 876 if ((e01 == e) || (e23 == e)) ++cellSize; 877 } 878 } 879 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 880 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 881 } 882 break; 883 case REFINER_HEX_3D: 884 /* All cells have 6 faces */ 885 for (c = cStart; c < cEnd; ++c) { 886 for (r = 0; r < 8; ++r) { 887 const PetscInt newp = (c - cStart)*8 + r; 888 889 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 890 } 891 } 892 /* Split faces have 4 edges and the same cells as the parent */ 893 for (f = fStart; f < fEnd; ++f) { 894 for (r = 0; r < 4; ++r) { 895 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 896 PetscInt size; 897 898 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 899 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 900 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 901 } 902 } 903 /* Interior faces have 4 edges and 2 cells */ 904 for (c = cStart; c < cEnd; ++c) { 905 for (r = 0; r < 12; ++r) { 906 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 907 908 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 909 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 910 } 911 } 912 /* Split edges have 2 vertices and the same faces as the parent */ 913 for (e = eStart; e < eEnd; ++e) { 914 for (r = 0; r < 2; ++r) { 915 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 916 PetscInt size; 917 918 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 919 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 920 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 921 } 922 } 923 /* Face edges have 2 vertices and 2+cells faces */ 924 for (f = fStart; f < fEnd; ++f) { 925 for (r = 0; r < 4; ++r) { 926 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 927 PetscInt size; 928 929 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 930 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 931 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 932 } 933 } 934 /* Cell edges have 2 vertices and 4 faces */ 935 for (c = cStart; c < cEnd; ++c) { 936 for (r = 0; r < 6; ++r) { 937 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 938 939 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 940 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 941 } 942 } 943 /* Old vertices have identical supports */ 944 for (v = vStart; v < vEnd; ++v) { 945 const PetscInt newp = vStartNew + (v - vStart); 946 PetscInt size; 947 948 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 949 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 950 } 951 /* Edge vertices have 2 + faces supports */ 952 for (e = eStart; e < eEnd; ++e) { 953 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 954 PetscInt size; 955 956 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 957 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 958 } 959 /* Face vertices have 4 + cells supports */ 960 for (f = fStart; f < fEnd; ++f) { 961 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 962 PetscInt size; 963 964 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 965 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 966 } 967 /* Cell vertices have 6 supports */ 968 for (c = cStart; c < cEnd; ++c) { 969 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 970 971 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 972 } 973 break; 974 case REFINER_HYBRID_HEX_3D: 975 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 976 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 977 /* Interior cells have 6 faces */ 978 for (c = cStart; c < cMax; ++c) { 979 for (r = 0; r < 8; ++r) { 980 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 981 982 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 983 } 984 } 985 /* Hybrid cells have 6 faces */ 986 for (c = cMax; c < cEnd; ++c) { 987 for (r = 0; r < 4; ++r) { 988 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 989 990 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 991 } 992 } 993 /* Interior split faces have 4 edges and the same cells as the parent */ 994 for (f = fStart; f < fMax; ++f) { 995 for (r = 0; r < 4; ++r) { 996 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 997 PetscInt size; 998 999 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1000 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1001 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1002 } 1003 } 1004 /* Interior cell faces have 4 edges and 2 cells */ 1005 for (c = cStart; c < cMax; ++c) { 1006 for (r = 0; r < 12; ++r) { 1007 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1008 1009 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1010 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1011 } 1012 } 1013 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1014 for (f = fMax; f < fEnd; ++f) { 1015 for (r = 0; r < 2; ++r) { 1016 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1017 PetscInt size; 1018 1019 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1020 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1021 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1022 } 1023 } 1024 /* Hybrid cells faces have 4 edges and 2 cells */ 1025 for (c = cMax; c < cEnd; ++c) { 1026 for (r = 0; r < 4; ++r) { 1027 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1028 1029 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1030 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1031 } 1032 } 1033 /* Interior split edges have 2 vertices and the same faces as the parent */ 1034 for (e = eStart; e < eMax; ++e) { 1035 for (r = 0; r < 2; ++r) { 1036 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1037 PetscInt size; 1038 1039 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1040 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1041 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1042 } 1043 } 1044 /* Interior face edges have 2 vertices and 2+cells faces */ 1045 for (f = fStart; f < fMax; ++f) { 1046 for (r = 0; r < 4; ++r) { 1047 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1048 PetscInt size; 1049 1050 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1051 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1052 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1053 } 1054 } 1055 /* Interior cell edges have 2 vertices and 4 faces */ 1056 for (c = cStart; c < cMax; ++c) { 1057 for (r = 0; r < 6; ++r) { 1058 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1059 1060 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1061 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1062 } 1063 } 1064 /* Hybrid edges have 2 vertices and the same faces */ 1065 for (e = eMax; e < eEnd; ++e) { 1066 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1067 PetscInt size; 1068 1069 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1070 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1071 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1072 } 1073 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1074 for (f = fMax; f < fEnd; ++f) { 1075 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 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 /* Hybrid cell edges have 2 vertices and 4 faces */ 1083 for (c = cMax; c < cEnd; ++c) { 1084 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1085 1086 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1087 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1088 } 1089 /* Interior vertices have identical supports */ 1090 for (v = vStart; v < vEnd; ++v) { 1091 const PetscInt newp = vStartNew + (v - vStart); 1092 PetscInt size; 1093 1094 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1095 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1096 } 1097 /* Interior edge vertices have 2 + faces supports */ 1098 for (e = eStart; e < eMax; ++e) { 1099 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1100 PetscInt size; 1101 1102 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1103 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1104 } 1105 /* Interior face vertices have 4 + cells supports */ 1106 for (f = fStart; f < fMax; ++f) { 1107 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1108 PetscInt size; 1109 1110 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1111 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1112 } 1113 /* Interior cell vertices have 6 supports */ 1114 for (c = cStart; c < cMax; ++c) { 1115 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1116 1117 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1118 } 1119 break; 1120 default: 1121 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1122 } 1123 PetscFunctionReturn(0); 1124 } 1125 1126 #undef __FUNCT__ 1127 #define __FUNCT__ "CellRefinerSetCones" 1128 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1129 { 1130 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1131 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1132 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1133 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 1134 PetscErrorCode ierr; 1135 1136 PetscFunctionBegin; 1137 if (!refiner) PetscFunctionReturn(0); 1138 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1139 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1140 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1141 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1142 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1143 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1144 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1145 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1146 switch (refiner) { 1147 case REFINER_SIMPLEX_1D: 1148 /* Max support size of refined mesh is 2 */ 1149 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1150 /* All cells have 2 vertices */ 1151 for (c = cStart; c < cEnd; ++c) { 1152 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1153 1154 for (r = 0; r < 2; ++r) { 1155 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1156 const PetscInt *cone; 1157 PetscInt coneNew[2]; 1158 1159 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1160 coneNew[0] = vStartNew + (cone[0] - vStart); 1161 coneNew[1] = vStartNew + (cone[1] - vStart); 1162 coneNew[(r+1)%2] = newv; 1163 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1164 #if 1 1165 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew); 1166 for (p = 0; p < 2; ++p) { 1167 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); 1168 } 1169 #endif 1170 } 1171 } 1172 /* Old vertices have identical supports */ 1173 for (v = vStart; v < vEnd; ++v) { 1174 const PetscInt newp = vStartNew + (v - vStart); 1175 const PetscInt *support, *cone; 1176 PetscInt size, s; 1177 1178 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1179 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1180 for (s = 0; s < size; ++s) { 1181 PetscInt r = 0; 1182 1183 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1184 if (cone[1] == v) r = 1; 1185 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1186 } 1187 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1188 #if 1 1189 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1190 for (p = 0; p < size; ++p) { 1191 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); 1192 } 1193 #endif 1194 } 1195 /* Cell vertices have support of 2 cells */ 1196 for (c = cStart; c < cEnd; ++c) { 1197 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1198 1199 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1200 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1201 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1202 #if 1 1203 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1204 for (p = 0; p < 2; ++p) { 1205 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); 1206 } 1207 #endif 1208 } 1209 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1210 break; 1211 case REFINER_SIMPLEX_2D: 1212 /* 1213 2 1214 |\ 1215 | \ 1216 | \ 1217 | \ 1218 | C \ 1219 | \ 1220 | \ 1221 2---1---1 1222 |\ D / \ 1223 | 2 0 \ 1224 |A \ / B \ 1225 0---0-------1 1226 */ 1227 /* All cells have 3 faces */ 1228 for (c = cStart; c < cEnd; ++c) { 1229 const PetscInt newp = cStartNew + (c - cStart)*4; 1230 const PetscInt *cone, *ornt; 1231 PetscInt coneNew[3], orntNew[3]; 1232 1233 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1234 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1235 /* A triangle */ 1236 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1237 orntNew[0] = ornt[0]; 1238 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1239 orntNew[1] = -2; 1240 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1241 orntNew[2] = ornt[2]; 1242 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1243 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1244 #if 1 1245 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); 1246 for (p = 0; p < 3; ++p) { 1247 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); 1248 } 1249 #endif 1250 /* B triangle */ 1251 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1252 orntNew[0] = ornt[0]; 1253 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1254 orntNew[1] = ornt[1]; 1255 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1256 orntNew[2] = -2; 1257 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1258 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1259 #if 1 1260 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); 1261 for (p = 0; p < 3; ++p) { 1262 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); 1263 } 1264 #endif 1265 /* C triangle */ 1266 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1267 orntNew[0] = -2; 1268 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1269 orntNew[1] = ornt[1]; 1270 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1271 orntNew[2] = ornt[2]; 1272 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1273 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1274 #if 1 1275 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); 1276 for (p = 0; p < 3; ++p) { 1277 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); 1278 } 1279 #endif 1280 /* D triangle */ 1281 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1282 orntNew[0] = 0; 1283 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1284 orntNew[1] = 0; 1285 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1286 orntNew[2] = 0; 1287 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1288 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1289 #if 1 1290 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); 1291 for (p = 0; p < 3; ++p) { 1292 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); 1293 } 1294 #endif 1295 } 1296 /* Split faces have 2 vertices and the same cells as the parent */ 1297 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1298 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1299 for (f = fStart; f < fEnd; ++f) { 1300 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1301 1302 for (r = 0; r < 2; ++r) { 1303 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1304 const PetscInt *cone, *ornt, *support; 1305 PetscInt coneNew[2], coneSize, c, supportSize, s; 1306 1307 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1308 coneNew[0] = vStartNew + (cone[0] - vStart); 1309 coneNew[1] = vStartNew + (cone[1] - vStart); 1310 coneNew[(r+1)%2] = newv; 1311 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1312 #if 1 1313 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1314 for (p = 0; p < 2; ++p) { 1315 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); 1316 } 1317 #endif 1318 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1319 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1320 for (s = 0; s < supportSize; ++s) { 1321 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1322 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1323 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1324 for (c = 0; c < coneSize; ++c) { 1325 if (cone[c] == f) break; 1326 } 1327 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1328 } 1329 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1330 #if 1 1331 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1332 for (p = 0; p < supportSize; ++p) { 1333 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); 1334 } 1335 #endif 1336 } 1337 } 1338 /* Interior faces have 2 vertices and 2 cells */ 1339 for (c = cStart; c < cEnd; ++c) { 1340 const PetscInt *cone; 1341 1342 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1343 for (r = 0; r < 3; ++r) { 1344 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1345 PetscInt coneNew[2]; 1346 PetscInt supportNew[2]; 1347 1348 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1349 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1350 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1351 #if 1 1352 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1353 for (p = 0; p < 2; ++p) { 1354 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); 1355 } 1356 #endif 1357 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1358 supportNew[1] = (c - cStart)*4 + 3; 1359 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1360 #if 1 1361 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1362 for (p = 0; p < 2; ++p) { 1363 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); 1364 } 1365 #endif 1366 } 1367 } 1368 /* Old vertices have identical supports */ 1369 for (v = vStart; v < vEnd; ++v) { 1370 const PetscInt newp = vStartNew + (v - vStart); 1371 const PetscInt *support, *cone; 1372 PetscInt size, s; 1373 1374 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1375 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1376 for (s = 0; s < size; ++s) { 1377 PetscInt r = 0; 1378 1379 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1380 if (cone[1] == v) r = 1; 1381 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1382 } 1383 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1384 #if 1 1385 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1386 for (p = 0; p < size; ++p) { 1387 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); 1388 } 1389 #endif 1390 } 1391 /* Face vertices have 2 + cells*2 supports */ 1392 for (f = fStart; f < fEnd; ++f) { 1393 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1394 const PetscInt *cone, *support; 1395 PetscInt size, s; 1396 1397 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1398 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1399 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1400 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1401 for (s = 0; s < size; ++s) { 1402 PetscInt r = 0; 1403 1404 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1405 if (cone[1] == f) r = 1; 1406 else if (cone[2] == f) r = 2; 1407 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1408 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1409 } 1410 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1411 #if 1 1412 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1413 for (p = 0; p < 2+size*2; ++p) { 1414 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); 1415 } 1416 #endif 1417 } 1418 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1419 break; 1420 case REFINER_HEX_2D: 1421 /* 1422 3---------2---------2 1423 | | | 1424 | D 2 C | 1425 | | | 1426 3----3----0----1----1 1427 | | | 1428 | A 0 B | 1429 | | | 1430 0---------0---------1 1431 */ 1432 /* All cells have 4 faces */ 1433 for (c = cStart; c < cEnd; ++c) { 1434 const PetscInt newp = (c - cStart)*4; 1435 const PetscInt *cone, *ornt; 1436 PetscInt coneNew[4], orntNew[4]; 1437 1438 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1439 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1440 /* A quad */ 1441 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1442 orntNew[0] = ornt[0]; 1443 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1444 orntNew[1] = 0; 1445 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1446 orntNew[2] = -2; 1447 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1448 orntNew[3] = ornt[3]; 1449 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1450 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1451 #if 1 1452 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); 1453 for (p = 0; p < 4; ++p) { 1454 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); 1455 } 1456 #endif 1457 /* B quad */ 1458 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1459 orntNew[0] = ornt[0]; 1460 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1461 orntNew[1] = ornt[1]; 1462 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1463 orntNew[2] = 0; 1464 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1465 orntNew[3] = -2; 1466 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1467 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1468 #if 1 1469 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); 1470 for (p = 0; p < 4; ++p) { 1471 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); 1472 } 1473 #endif 1474 /* C quad */ 1475 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1476 orntNew[0] = -2; 1477 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1478 orntNew[1] = ornt[1]; 1479 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1480 orntNew[2] = ornt[2]; 1481 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1482 orntNew[3] = 0; 1483 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1484 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1485 #if 1 1486 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); 1487 for (p = 0; p < 4; ++p) { 1488 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); 1489 } 1490 #endif 1491 /* D quad */ 1492 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1493 orntNew[0] = 0; 1494 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1495 orntNew[1] = -2; 1496 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1497 orntNew[2] = ornt[2]; 1498 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1499 orntNew[3] = ornt[3]; 1500 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1501 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1502 #if 1 1503 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); 1504 for (p = 0; p < 4; ++p) { 1505 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); 1506 } 1507 #endif 1508 } 1509 /* Split faces have 2 vertices and the same cells as the parent */ 1510 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1511 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1512 for (f = fStart; f < fEnd; ++f) { 1513 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1514 1515 for (r = 0; r < 2; ++r) { 1516 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1517 const PetscInt *cone, *ornt, *support; 1518 PetscInt coneNew[2], coneSize, c, supportSize, s; 1519 1520 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1521 coneNew[0] = vStartNew + (cone[0] - vStart); 1522 coneNew[1] = vStartNew + (cone[1] - vStart); 1523 coneNew[(r+1)%2] = newv; 1524 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1525 #if 1 1526 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1527 for (p = 0; p < 2; ++p) { 1528 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); 1529 } 1530 #endif 1531 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1532 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1533 for (s = 0; s < supportSize; ++s) { 1534 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1535 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1536 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1537 for (c = 0; c < coneSize; ++c) { 1538 if (cone[c] == f) break; 1539 } 1540 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1541 } 1542 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1543 #if 1 1544 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1545 for (p = 0; p < supportSize; ++p) { 1546 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); 1547 } 1548 #endif 1549 } 1550 } 1551 /* Interior faces have 2 vertices and 2 cells */ 1552 for (c = cStart; c < cEnd; ++c) { 1553 const PetscInt *cone; 1554 PetscInt coneNew[2], supportNew[2]; 1555 1556 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1557 for (r = 0; r < 4; ++r) { 1558 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1559 1560 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1561 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1562 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1563 #if 1 1564 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1565 for (p = 0; p < 2; ++p) { 1566 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); 1567 } 1568 #endif 1569 supportNew[0] = (c - cStart)*4 + r; 1570 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1571 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1572 #if 1 1573 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1574 for (p = 0; p < 2; ++p) { 1575 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); 1576 } 1577 #endif 1578 } 1579 } 1580 /* Old vertices have identical supports */ 1581 for (v = vStart; v < vEnd; ++v) { 1582 const PetscInt newp = vStartNew + (v - vStart); 1583 const PetscInt *support, *cone; 1584 PetscInt size, s; 1585 1586 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1587 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1588 for (s = 0; s < size; ++s) { 1589 PetscInt r = 0; 1590 1591 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1592 if (cone[1] == v) r = 1; 1593 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1594 } 1595 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1596 #if 1 1597 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1598 for (p = 0; p < size; ++p) { 1599 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); 1600 } 1601 #endif 1602 } 1603 /* Face vertices have 2 + cells supports */ 1604 for (f = fStart; f < fEnd; ++f) { 1605 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1606 const PetscInt *cone, *support; 1607 PetscInt size, s; 1608 1609 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1610 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1611 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1612 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1613 for (s = 0; s < size; ++s) { 1614 PetscInt r = 0; 1615 1616 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1617 if (cone[1] == f) r = 1; 1618 else if (cone[2] == f) r = 2; 1619 else if (cone[3] == f) r = 3; 1620 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1621 } 1622 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1623 #if 1 1624 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1625 for (p = 0; p < 2+size; ++p) { 1626 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); 1627 } 1628 #endif 1629 } 1630 /* Cell vertices have 4 supports */ 1631 for (c = cStart; c < cEnd; ++c) { 1632 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1633 PetscInt supportNew[4]; 1634 1635 for (r = 0; r < 4; ++r) { 1636 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1637 } 1638 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1639 } 1640 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1641 break; 1642 case REFINER_HYBRID_SIMPLEX_2D: 1643 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1644 cMax = PetscMin(cEnd, cMax); 1645 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1646 fMax = PetscMin(fEnd, fMax); 1647 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1648 /* Interior cells have 3 faces */ 1649 for (c = cStart; c < cMax; ++c) { 1650 const PetscInt newp = cStartNew + (c - cStart)*4; 1651 const PetscInt *cone, *ornt; 1652 PetscInt coneNew[3], orntNew[3]; 1653 1654 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1655 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1656 /* A triangle */ 1657 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1658 orntNew[0] = ornt[0]; 1659 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1660 orntNew[1] = -2; 1661 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1662 orntNew[2] = ornt[2]; 1663 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1664 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1665 #if 1 1666 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); 1667 for (p = 0; p < 3; ++p) { 1668 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); 1669 } 1670 #endif 1671 /* B triangle */ 1672 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1673 orntNew[0] = ornt[0]; 1674 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1675 orntNew[1] = ornt[1]; 1676 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1677 orntNew[2] = -2; 1678 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1679 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1680 #if 1 1681 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); 1682 for (p = 0; p < 3; ++p) { 1683 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); 1684 } 1685 #endif 1686 /* C triangle */ 1687 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1688 orntNew[0] = -2; 1689 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1690 orntNew[1] = ornt[1]; 1691 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1692 orntNew[2] = ornt[2]; 1693 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1694 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1695 #if 1 1696 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); 1697 for (p = 0; p < 3; ++p) { 1698 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); 1699 } 1700 #endif 1701 /* D triangle */ 1702 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1703 orntNew[0] = 0; 1704 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1705 orntNew[1] = 0; 1706 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1707 orntNew[2] = 0; 1708 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1709 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1710 #if 1 1711 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); 1712 for (p = 0; p < 3; ++p) { 1713 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); 1714 } 1715 #endif 1716 } 1717 /* 1718 2----3----3 1719 | | 1720 | B | 1721 | | 1722 0----4--- 1 1723 | | 1724 | A | 1725 | | 1726 0----2----1 1727 */ 1728 /* Hybrid cells have 4 faces */ 1729 for (c = cMax; c < cEnd; ++c) { 1730 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1731 const PetscInt *cone, *ornt; 1732 PetscInt coneNew[4], orntNew[4], r; 1733 1734 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1735 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1736 r = (ornt[0] < 0 ? 1 : 0); 1737 /* A quad */ 1738 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 1739 orntNew[0] = ornt[0]; 1740 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 1741 orntNew[1] = ornt[1]; 1742 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 1743 orntNew[2+r] = 0; 1744 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1745 orntNew[3-r] = 0; 1746 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1747 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1748 #if 1 1749 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); 1750 for (p = 0; p < 4; ++p) { 1751 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); 1752 } 1753 #endif 1754 /* B quad */ 1755 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 1756 orntNew[0] = ornt[0]; 1757 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 1758 orntNew[1] = ornt[1]; 1759 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1760 orntNew[2+r] = 0; 1761 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 1762 orntNew[3-r] = 0; 1763 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1764 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1765 #if 1 1766 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); 1767 for (p = 0; p < 4; ++p) { 1768 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); 1769 } 1770 #endif 1771 } 1772 /* Interior split faces have 2 vertices and the same cells as the parent */ 1773 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1774 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1775 for (f = fStart; f < fMax; ++f) { 1776 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1777 1778 for (r = 0; r < 2; ++r) { 1779 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1780 const PetscInt *cone, *ornt, *support; 1781 PetscInt coneNew[2], coneSize, c, supportSize, s; 1782 1783 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1784 coneNew[0] = vStartNew + (cone[0] - vStart); 1785 coneNew[1] = vStartNew + (cone[1] - vStart); 1786 coneNew[(r+1)%2] = newv; 1787 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1788 #if 1 1789 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1790 for (p = 0; p < 2; ++p) { 1791 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); 1792 } 1793 #endif 1794 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1795 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1796 for (s = 0; s < supportSize; ++s) { 1797 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1798 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1799 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1800 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 1801 if (support[s] >= cMax) { 1802 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 1803 } else { 1804 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1805 } 1806 } 1807 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1808 #if 1 1809 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1810 for (p = 0; p < supportSize; ++p) { 1811 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); 1812 } 1813 #endif 1814 } 1815 } 1816 /* Interior cell faces have 2 vertices and 2 cells */ 1817 for (c = cStart; c < cMax; ++c) { 1818 const PetscInt *cone; 1819 1820 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1821 for (r = 0; r < 3; ++r) { 1822 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1823 PetscInt coneNew[2]; 1824 PetscInt supportNew[2]; 1825 1826 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1827 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1828 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1829 #if 1 1830 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1831 for (p = 0; p < 2; ++p) { 1832 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); 1833 } 1834 #endif 1835 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1836 supportNew[1] = (c - cStart)*4 + 3; 1837 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1838 #if 1 1839 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1840 for (p = 0; p < 2; ++p) { 1841 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); 1842 } 1843 #endif 1844 } 1845 } 1846 /* Interior hybrid faces have 2 vertices and the same cells */ 1847 for (f = fMax; f < fEnd; ++f) { 1848 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1849 const PetscInt *cone, *ornt; 1850 const PetscInt *support; 1851 PetscInt coneNew[2]; 1852 PetscInt supportNew[2]; 1853 PetscInt size, s, r; 1854 1855 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1856 coneNew[0] = vStartNew + (cone[0] - vStart); 1857 coneNew[1] = vStartNew + (cone[1] - vStart); 1858 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1859 #if 1 1860 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1861 for (p = 0; p < 2; ++p) { 1862 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); 1863 } 1864 #endif 1865 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1866 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1867 for (s = 0; s < size; ++s) { 1868 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1869 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1870 for (r = 0; r < 2; ++r) { 1871 if (cone[r+2] == f) break; 1872 } 1873 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 1874 } 1875 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1876 #if 1 1877 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1878 for (p = 0; p < size; ++p) { 1879 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); 1880 } 1881 #endif 1882 } 1883 /* Cell hybrid faces have 2 vertices and 2 cells */ 1884 for (c = cMax; c < cEnd; ++c) { 1885 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1886 const PetscInt *cone; 1887 PetscInt coneNew[2]; 1888 PetscInt supportNew[2]; 1889 1890 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1891 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1892 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1893 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1894 #if 1 1895 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1896 for (p = 0; p < 2; ++p) { 1897 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); 1898 } 1899 #endif 1900 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1901 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1902 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1903 #if 1 1904 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1905 for (p = 0; p < 2; ++p) { 1906 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); 1907 } 1908 #endif 1909 } 1910 /* Old vertices have identical supports */ 1911 for (v = vStart; v < vEnd; ++v) { 1912 const PetscInt newp = vStartNew + (v - vStart); 1913 const PetscInt *support, *cone; 1914 PetscInt size, s; 1915 1916 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1917 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1918 for (s = 0; s < size; ++s) { 1919 if (support[s] >= fMax) { 1920 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1921 } else { 1922 PetscInt r = 0; 1923 1924 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1925 if (cone[1] == v) r = 1; 1926 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1927 } 1928 } 1929 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1930 #if 1 1931 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1932 for (p = 0; p < size; ++p) { 1933 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); 1934 } 1935 #endif 1936 } 1937 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1938 for (f = fStart; f < fMax; ++f) { 1939 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1940 const PetscInt *cone, *support; 1941 PetscInt size, newSize = 2, s; 1942 1943 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1944 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1945 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1946 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1947 for (s = 0; s < size; ++s) { 1948 PetscInt r = 0; 1949 1950 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1951 if (support[s] >= cMax) { 1952 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1953 1954 newSize += 1; 1955 } else { 1956 if (cone[1] == f) r = 1; 1957 else if (cone[2] == f) r = 2; 1958 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1959 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1960 1961 newSize += 2; 1962 } 1963 } 1964 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1965 #if 1 1966 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1967 for (p = 0; p < newSize; ++p) { 1968 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); 1969 } 1970 #endif 1971 } 1972 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1973 break; 1974 case REFINER_HYBRID_HEX_2D: 1975 /* Hybrid Hex 2D */ 1976 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1977 cMax = PetscMin(cEnd, cMax); 1978 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1979 fMax = PetscMin(fEnd, fMax); 1980 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1981 /* Interior cells have 4 faces */ 1982 for (c = cStart; c < cMax; ++c) { 1983 const PetscInt newp = cStartNew + (c - cStart)*4; 1984 const PetscInt *cone, *ornt; 1985 PetscInt coneNew[4], orntNew[4]; 1986 1987 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1988 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1989 /* A quad */ 1990 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1991 orntNew[0] = ornt[0]; 1992 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1993 orntNew[1] = 0; 1994 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1995 orntNew[2] = -2; 1996 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1997 orntNew[3] = ornt[3]; 1998 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1999 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2000 #if 1 2001 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); 2002 for (p = 0; p < 4; ++p) { 2003 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); 2004 } 2005 #endif 2006 /* B quad */ 2007 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2008 orntNew[0] = ornt[0]; 2009 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2010 orntNew[1] = ornt[1]; 2011 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2012 orntNew[2] = 0; 2013 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 2014 orntNew[3] = -2; 2015 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2016 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2017 #if 1 2018 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); 2019 for (p = 0; p < 4; ++p) { 2020 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); 2021 } 2022 #endif 2023 /* C quad */ 2024 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2025 orntNew[0] = -2; 2026 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2027 orntNew[1] = ornt[1]; 2028 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2029 orntNew[2] = ornt[2]; 2030 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2031 orntNew[3] = 0; 2032 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2033 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2034 #if 1 2035 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); 2036 for (p = 0; p < 4; ++p) { 2037 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); 2038 } 2039 #endif 2040 /* D quad */ 2041 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2042 orntNew[0] = 0; 2043 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2044 orntNew[1] = -2; 2045 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2046 orntNew[2] = ornt[2]; 2047 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2048 orntNew[3] = ornt[3]; 2049 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2050 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2051 #if 1 2052 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); 2053 for (p = 0; p < 4; ++p) { 2054 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); 2055 } 2056 #endif 2057 } 2058 /* 2059 2----3----3 2060 | | 2061 | B | 2062 | | 2063 0----4--- 1 2064 | | 2065 | A | 2066 | | 2067 0----2----1 2068 */ 2069 /* Hybrid cells have 4 faces */ 2070 for (c = cMax; c < cEnd; ++c) { 2071 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2072 const PetscInt *cone, *ornt; 2073 PetscInt coneNew[4], orntNew[4]; 2074 2075 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2076 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2077 /* A quad */ 2078 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2079 orntNew[0] = ornt[0]; 2080 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2081 orntNew[1] = ornt[1]; 2082 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 2083 orntNew[2] = 0; 2084 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2085 orntNew[3] = 0; 2086 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2087 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2088 #if 1 2089 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); 2090 for (p = 0; p < 4; ++p) { 2091 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); 2092 } 2093 #endif 2094 /* B quad */ 2095 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2096 orntNew[0] = ornt[0]; 2097 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2098 orntNew[1] = ornt[1]; 2099 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2100 orntNew[2] = 0; 2101 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 2102 orntNew[3] = 0; 2103 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2104 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2105 #if 1 2106 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); 2107 for (p = 0; p < 4; ++p) { 2108 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); 2109 } 2110 #endif 2111 } 2112 /* Interior split faces have 2 vertices and the same cells as the parent */ 2113 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2114 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2115 for (f = fStart; f < fMax; ++f) { 2116 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2117 2118 for (r = 0; r < 2; ++r) { 2119 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2120 const PetscInt *cone, *ornt, *support; 2121 PetscInt coneNew[2], coneSize, c, supportSize, s; 2122 2123 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2124 coneNew[0] = vStartNew + (cone[0] - vStart); 2125 coneNew[1] = vStartNew + (cone[1] - vStart); 2126 coneNew[(r+1)%2] = newv; 2127 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2128 #if 1 2129 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2130 for (p = 0; p < 2; ++p) { 2131 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); 2132 } 2133 #endif 2134 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2135 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2136 for (s = 0; s < supportSize; ++s) { 2137 if (support[s] >= cMax) { 2138 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2139 } else { 2140 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2141 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2142 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2143 for (c = 0; c < coneSize; ++c) { 2144 if (cone[c] == f) break; 2145 } 2146 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2147 } 2148 } 2149 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2150 #if 1 2151 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2152 for (p = 0; p < supportSize; ++p) { 2153 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); 2154 } 2155 #endif 2156 } 2157 } 2158 /* Interior cell faces have 2 vertices and 2 cells */ 2159 for (c = cStart; c < cMax; ++c) { 2160 const PetscInt *cone; 2161 2162 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2163 for (r = 0; r < 4; ++r) { 2164 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2165 PetscInt coneNew[2], supportNew[2]; 2166 2167 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2168 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2169 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2170 #if 1 2171 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2172 for (p = 0; p < 2; ++p) { 2173 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); 2174 } 2175 #endif 2176 supportNew[0] = (c - cStart)*4 + r; 2177 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2178 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2179 #if 1 2180 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2181 for (p = 0; p < 2; ++p) { 2182 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); 2183 } 2184 #endif 2185 } 2186 } 2187 /* Hybrid faces have 2 vertices and the same cells */ 2188 for (f = fMax; f < fEnd; ++f) { 2189 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 2190 const PetscInt *cone, *support; 2191 PetscInt coneNew[2], supportNew[2]; 2192 PetscInt size, s, r; 2193 2194 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2195 coneNew[0] = vStartNew + (cone[0] - vStart); 2196 coneNew[1] = vStartNew + (cone[1] - vStart); 2197 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2198 #if 1 2199 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2200 for (p = 0; p < 2; ++p) { 2201 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); 2202 } 2203 #endif 2204 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2205 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2206 for (s = 0; s < size; ++s) { 2207 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2208 for (r = 0; r < 2; ++r) { 2209 if (cone[r+2] == f) break; 2210 } 2211 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2212 } 2213 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2214 #if 1 2215 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2216 for (p = 0; p < size; ++p) { 2217 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); 2218 } 2219 #endif 2220 } 2221 /* Cell hybrid faces have 2 vertices and 2 cells */ 2222 for (c = cMax; c < cEnd; ++c) { 2223 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2224 const PetscInt *cone; 2225 PetscInt coneNew[2], supportNew[2]; 2226 2227 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2228 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2229 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2230 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2231 #if 1 2232 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2233 for (p = 0; p < 2; ++p) { 2234 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); 2235 } 2236 #endif 2237 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2238 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2239 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2240 #if 1 2241 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2242 for (p = 0; p < 2; ++p) { 2243 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); 2244 } 2245 #endif 2246 } 2247 /* Old vertices have identical supports */ 2248 for (v = vStart; v < vEnd; ++v) { 2249 const PetscInt newp = vStartNew + (v - vStart); 2250 const PetscInt *support, *cone; 2251 PetscInt size, s; 2252 2253 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2254 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2255 for (s = 0; s < size; ++s) { 2256 if (support[s] >= fMax) { 2257 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2258 } else { 2259 PetscInt r = 0; 2260 2261 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2262 if (cone[1] == v) r = 1; 2263 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2264 } 2265 } 2266 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2267 #if 1 2268 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2269 for (p = 0; p < size; ++p) { 2270 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); 2271 } 2272 #endif 2273 } 2274 /* Face vertices have 2 + cells supports */ 2275 for (f = fStart; f < fMax; ++f) { 2276 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2277 const PetscInt *cone, *support; 2278 PetscInt size, s; 2279 2280 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2281 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2282 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2283 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2284 for (s = 0; s < size; ++s) { 2285 PetscInt r = 0; 2286 2287 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2288 if (support[s] >= cMax) { 2289 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2290 } else { 2291 if (cone[1] == f) r = 1; 2292 else if (cone[2] == f) r = 2; 2293 else if (cone[3] == f) r = 3; 2294 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2295 } 2296 } 2297 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2298 #if 1 2299 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2300 for (p = 0; p < 2+size; ++p) { 2301 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); 2302 } 2303 #endif 2304 } 2305 /* Cell vertices have 4 supports */ 2306 for (c = cStart; c < cMax; ++c) { 2307 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2308 PetscInt supportNew[4]; 2309 2310 for (r = 0; r < 4; ++r) { 2311 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2312 } 2313 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2314 } 2315 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2316 break; 2317 case REFINER_SIMPLEX_3D: 2318 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2319 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2320 for (c = cStart; c < cEnd; ++c) { 2321 const PetscInt newp = cStartNew + (c - cStart)*8; 2322 const PetscInt *cone, *ornt; 2323 PetscInt coneNew[4], orntNew[4]; 2324 2325 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2326 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2327 /* A tetrahedron: {0, a, c, d} */ 2328 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2329 orntNew[0] = ornt[0]; 2330 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2331 orntNew[1] = ornt[1]; 2332 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2333 orntNew[2] = ornt[2]; 2334 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2335 orntNew[3] = 0; 2336 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2337 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2338 #if 1 2339 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); 2340 for (p = 0; p < 4; ++p) { 2341 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); 2342 } 2343 #endif 2344 /* B tetrahedron: {a, 1, b, e} */ 2345 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2346 orntNew[0] = ornt[0]; 2347 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2348 orntNew[1] = ornt[1]; 2349 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2350 orntNew[2] = 0; 2351 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2352 orntNew[3] = ornt[3]; 2353 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2354 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2355 #if 1 2356 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); 2357 for (p = 0; p < 4; ++p) { 2358 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); 2359 } 2360 #endif 2361 /* C tetrahedron: {c, b, 2, f} */ 2362 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2363 orntNew[0] = ornt[0]; 2364 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2365 orntNew[1] = 0; 2366 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2367 orntNew[2] = ornt[2]; 2368 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2369 orntNew[3] = ornt[3]; 2370 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2371 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2372 #if 1 2373 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); 2374 for (p = 0; p < 4; ++p) { 2375 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); 2376 } 2377 #endif 2378 /* D tetrahedron: {d, e, f, 3} */ 2379 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2380 orntNew[0] = 0; 2381 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2382 orntNew[1] = ornt[1]; 2383 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2384 orntNew[2] = ornt[2]; 2385 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2386 orntNew[3] = ornt[3]; 2387 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2388 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2389 #if 1 2390 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); 2391 for (p = 0; p < 4; ++p) { 2392 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); 2393 } 2394 #endif 2395 /* A' tetrahedron: {d, a, c, f} */ 2396 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2397 orntNew[0] = -3; 2398 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2399 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2400 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2401 orntNew[2] = 0; 2402 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2403 orntNew[3] = 2; 2404 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2405 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2406 #if 1 2407 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); 2408 for (p = 0; p < 4; ++p) { 2409 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); 2410 } 2411 #endif 2412 /* B' tetrahedron: {e, b, a, f} */ 2413 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2414 orntNew[0] = -3; 2415 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2416 orntNew[1] = 1; 2417 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2418 orntNew[2] = 0; 2419 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2420 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2421 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2422 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2423 #if 1 2424 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); 2425 for (p = 0; p < 4; ++p) { 2426 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); 2427 } 2428 #endif 2429 /* C' tetrahedron: {b, f, c, a} */ 2430 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2431 orntNew[0] = -3; 2432 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2433 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2434 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2435 orntNew[2] = -3; 2436 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2437 orntNew[3] = -2; 2438 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2439 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2440 #if 1 2441 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); 2442 for (p = 0; p < 4; ++p) { 2443 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); 2444 } 2445 #endif 2446 /* D' tetrahedron: {f, e, d, a} */ 2447 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2448 orntNew[0] = -3; 2449 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2450 orntNew[1] = -3; 2451 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2452 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2453 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2454 orntNew[3] = -3; 2455 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2456 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2457 #if 1 2458 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); 2459 for (p = 0; p < 4; ++p) { 2460 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); 2461 } 2462 #endif 2463 } 2464 /* Split faces have 3 edges and the same cells as the parent */ 2465 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2466 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2467 for (f = fStart; f < fEnd; ++f) { 2468 const PetscInt newp = fStartNew + (f - fStart)*4; 2469 const PetscInt *cone, *ornt, *support; 2470 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2471 2472 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2473 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2474 /* A triangle */ 2475 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2476 orntNew[0] = ornt[0]; 2477 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2478 orntNew[1] = -2; 2479 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2480 orntNew[2] = ornt[2]; 2481 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2482 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2483 #if 1 2484 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); 2485 for (p = 0; p < 3; ++p) { 2486 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); 2487 } 2488 #endif 2489 /* B triangle */ 2490 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2491 orntNew[0] = ornt[0]; 2492 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2493 orntNew[1] = ornt[1]; 2494 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2495 orntNew[2] = -2; 2496 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2497 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2498 #if 1 2499 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); 2500 for (p = 0; p < 3; ++p) { 2501 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); 2502 } 2503 #endif 2504 /* C triangle */ 2505 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2506 orntNew[0] = -2; 2507 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2508 orntNew[1] = ornt[1]; 2509 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2510 orntNew[2] = ornt[2]; 2511 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2512 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2513 #if 1 2514 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); 2515 for (p = 0; p < 3; ++p) { 2516 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); 2517 } 2518 #endif 2519 /* D triangle */ 2520 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2521 orntNew[0] = 0; 2522 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2523 orntNew[1] = 0; 2524 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2525 orntNew[2] = 0; 2526 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2527 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2528 #if 1 2529 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); 2530 for (p = 0; p < 3; ++p) { 2531 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); 2532 } 2533 #endif 2534 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2535 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2536 for (r = 0; r < 4; ++r) { 2537 for (s = 0; s < supportSize; ++s) { 2538 PetscInt subf; 2539 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2540 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2541 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2542 for (c = 0; c < coneSize; ++c) { 2543 if (cone[c] == f) break; 2544 } 2545 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2546 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2547 } 2548 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2549 #if 1 2550 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); 2551 for (p = 0; p < supportSize; ++p) { 2552 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); 2553 } 2554 #endif 2555 } 2556 } 2557 /* Interior faces have 3 edges and 2 cells */ 2558 for (c = cStart; c < cEnd; ++c) { 2559 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2560 const PetscInt *cone, *ornt; 2561 PetscInt coneNew[3], orntNew[3]; 2562 PetscInt supportNew[2]; 2563 2564 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2565 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2566 /* Face A: {c, a, d} */ 2567 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2568 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2569 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2570 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2571 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2572 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2573 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2574 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2575 #if 1 2576 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2577 for (p = 0; p < 3; ++p) { 2578 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); 2579 } 2580 #endif 2581 supportNew[0] = (c - cStart)*8 + 0; 2582 supportNew[1] = (c - cStart)*8 + 0+4; 2583 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2584 #if 1 2585 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2586 for (p = 0; p < 2; ++p) { 2587 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); 2588 } 2589 #endif 2590 ++newp; 2591 /* Face B: {a, b, e} */ 2592 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2593 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2594 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2595 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2596 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2597 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2598 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2599 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2600 #if 1 2601 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2602 for (p = 0; p < 3; ++p) { 2603 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); 2604 } 2605 #endif 2606 supportNew[0] = (c - cStart)*8 + 1; 2607 supportNew[1] = (c - cStart)*8 + 1+4; 2608 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2609 #if 1 2610 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2611 for (p = 0; p < 2; ++p) { 2612 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); 2613 } 2614 #endif 2615 ++newp; 2616 /* Face C: {c, f, b} */ 2617 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2618 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2619 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2620 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2621 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2622 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2623 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2624 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2625 #if 1 2626 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2627 for (p = 0; p < 3; ++p) { 2628 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); 2629 } 2630 #endif 2631 supportNew[0] = (c - cStart)*8 + 2; 2632 supportNew[1] = (c - cStart)*8 + 2+4; 2633 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2634 #if 1 2635 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2636 for (p = 0; p < 2; ++p) { 2637 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); 2638 } 2639 #endif 2640 ++newp; 2641 /* Face D: {d, e, f} */ 2642 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2643 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2644 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2645 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2646 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2647 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2648 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2649 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2650 #if 1 2651 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2652 for (p = 0; p < 3; ++p) { 2653 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); 2654 } 2655 #endif 2656 supportNew[0] = (c - cStart)*8 + 3; 2657 supportNew[1] = (c - cStart)*8 + 3+4; 2658 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2659 #if 1 2660 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2661 for (p = 0; p < 2; ++p) { 2662 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); 2663 } 2664 #endif 2665 ++newp; 2666 /* Face E: {d, f, a} */ 2667 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2668 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2669 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2670 orntNew[1] = -2; 2671 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2672 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2673 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2674 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2675 #if 1 2676 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2677 for (p = 0; p < 3; ++p) { 2678 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); 2679 } 2680 #endif 2681 supportNew[0] = (c - cStart)*8 + 0+4; 2682 supportNew[1] = (c - cStart)*8 + 3+4; 2683 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2684 #if 1 2685 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2686 for (p = 0; p < 2; ++p) { 2687 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); 2688 } 2689 #endif 2690 ++newp; 2691 /* Face F: {c, a, f} */ 2692 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2693 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2694 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2695 orntNew[1] = 0; 2696 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2697 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2698 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2699 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2700 #if 1 2701 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2702 for (p = 0; p < 3; ++p) { 2703 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); 2704 } 2705 #endif 2706 supportNew[0] = (c - cStart)*8 + 0+4; 2707 supportNew[1] = (c - cStart)*8 + 2+4; 2708 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2709 #if 1 2710 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2711 for (p = 0; p < 2; ++p) { 2712 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); 2713 } 2714 #endif 2715 ++newp; 2716 /* Face G: {e, a, f} */ 2717 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2718 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2719 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2720 orntNew[1] = 0; 2721 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2722 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2723 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2724 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2725 #if 1 2726 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2727 for (p = 0; p < 3; ++p) { 2728 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); 2729 } 2730 #endif 2731 supportNew[0] = (c - cStart)*8 + 1+4; 2732 supportNew[1] = (c - cStart)*8 + 3+4; 2733 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2734 #if 1 2735 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2736 for (p = 0; p < 2; ++p) { 2737 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); 2738 } 2739 #endif 2740 ++newp; 2741 /* Face H: {a, b, f} */ 2742 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2743 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2744 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2745 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2746 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2747 orntNew[2] = -2; 2748 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2749 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2750 #if 1 2751 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2752 for (p = 0; p < 3; ++p) { 2753 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); 2754 } 2755 #endif 2756 supportNew[0] = (c - cStart)*8 + 1+4; 2757 supportNew[1] = (c - cStart)*8 + 2+4; 2758 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2759 #if 1 2760 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2761 for (p = 0; p < 2; ++p) { 2762 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); 2763 } 2764 #endif 2765 ++newp; 2766 } 2767 /* Split Edges have 2 vertices and the same faces as the parent */ 2768 for (e = eStart; e < eEnd; ++e) { 2769 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2770 2771 for (r = 0; r < 2; ++r) { 2772 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2773 const PetscInt *cone, *ornt, *support; 2774 PetscInt coneNew[2], coneSize, c, supportSize, s; 2775 2776 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2777 coneNew[0] = vStartNew + (cone[0] - vStart); 2778 coneNew[1] = vStartNew + (cone[1] - vStart); 2779 coneNew[(r+1)%2] = newv; 2780 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2781 #if 1 2782 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2783 for (p = 0; p < 2; ++p) { 2784 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); 2785 } 2786 #endif 2787 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2788 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2789 for (s = 0; s < supportSize; ++s) { 2790 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2791 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2792 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2793 for (c = 0; c < coneSize; ++c) { 2794 if (cone[c] == e) break; 2795 } 2796 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2797 } 2798 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2799 #if 1 2800 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2801 for (p = 0; p < supportSize; ++p) { 2802 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); 2803 } 2804 #endif 2805 } 2806 } 2807 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2808 for (f = fStart; f < fEnd; ++f) { 2809 const PetscInt *cone, *ornt, *support; 2810 PetscInt coneSize, supportSize, s; 2811 2812 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2813 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2814 for (r = 0; r < 3; ++r) { 2815 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2816 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2817 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2818 -1, -1, 1, 6, 0, 4, 2819 2, 5, 3, 4, -1, -1, 2820 -1, -1, 3, 6, 2, 7}; 2821 2822 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2823 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2824 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2825 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2826 #if 1 2827 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2828 for (p = 0; p < 2; ++p) { 2829 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); 2830 } 2831 #endif 2832 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2833 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2834 for (s = 0; s < supportSize; ++s) { 2835 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2836 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2837 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2838 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2839 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2840 er = GetTetSomethingInverse_Static(ornt[c], r); 2841 if (er == eint[c]) { 2842 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2843 } else { 2844 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2845 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2846 } 2847 } 2848 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2849 #if 1 2850 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2851 for (p = 0; p < intFaces; ++p) { 2852 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); 2853 } 2854 #endif 2855 } 2856 } 2857 /* Interior edges have 2 vertices and 4 faces */ 2858 for (c = cStart; c < cEnd; ++c) { 2859 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2860 const PetscInt *cone, *ornt, *fcone; 2861 PetscInt coneNew[2], supportNew[4], find; 2862 2863 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2864 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2865 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2866 find = GetTriEdge_Static(ornt[0], 0); 2867 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2868 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2869 find = GetTriEdge_Static(ornt[2], 1); 2870 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2871 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2872 #if 1 2873 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2874 for (p = 0; p < 2; ++p) { 2875 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); 2876 } 2877 #endif 2878 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2879 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2880 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2881 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2882 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2883 #if 1 2884 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2885 for (p = 0; p < 4; ++p) { 2886 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); 2887 } 2888 #endif 2889 } 2890 /* Old vertices have identical supports */ 2891 for (v = vStart; v < vEnd; ++v) { 2892 const PetscInt newp = vStartNew + (v - vStart); 2893 const PetscInt *support, *cone; 2894 PetscInt size, s; 2895 2896 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2897 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2898 for (s = 0; s < size; ++s) { 2899 PetscInt r = 0; 2900 2901 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2902 if (cone[1] == v) r = 1; 2903 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2904 } 2905 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2906 #if 1 2907 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2908 for (p = 0; p < size; ++p) { 2909 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); 2910 } 2911 #endif 2912 } 2913 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2914 for (e = eStart; e < eEnd; ++e) { 2915 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2916 const PetscInt *cone, *support; 2917 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2918 2919 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2920 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2921 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2922 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2923 for (s = 0; s < size; ++s) { 2924 PetscInt r = 0; 2925 2926 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2927 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2928 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2929 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2930 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2931 } 2932 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2933 for (s = 0; s < starSize*2; s += 2) { 2934 const PetscInt *cone, *ornt; 2935 PetscInt e01, e23; 2936 2937 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2938 /* Check edge 0-1 */ 2939 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2940 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2941 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2942 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2943 /* Check edge 2-3 */ 2944 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2945 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2946 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2947 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2948 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2949 } 2950 } 2951 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2952 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2953 #if 1 2954 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2955 for (p = 0; p < 2+size*2+cellSize; ++p) { 2956 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); 2957 } 2958 #endif 2959 } 2960 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2961 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2962 break; 2963 case REFINER_HYBRID_SIMPLEX_3D: 2964 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2965 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2966 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2967 for (c = cStart; c < cMax; ++c) { 2968 const PetscInt newp = cStartNew + (c - cStart)*8; 2969 const PetscInt *cone, *ornt; 2970 PetscInt coneNew[4], orntNew[4]; 2971 2972 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2973 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2974 /* A tetrahedron: {0, a, c, d} */ 2975 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2976 orntNew[0] = ornt[0]; 2977 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2978 orntNew[1] = ornt[1]; 2979 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2980 orntNew[2] = ornt[2]; 2981 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2982 orntNew[3] = 0; 2983 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2984 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2985 #if 1 2986 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); 2987 for (p = 0; p < 4; ++p) { 2988 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); 2989 } 2990 #endif 2991 /* B tetrahedron: {a, 1, b, e} */ 2992 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2993 orntNew[0] = ornt[0]; 2994 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2995 orntNew[1] = ornt[1]; 2996 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2997 orntNew[2] = 0; 2998 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2999 orntNew[3] = ornt[3]; 3000 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3001 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3002 #if 1 3003 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); 3004 for (p = 0; p < 4; ++p) { 3005 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); 3006 } 3007 #endif 3008 /* C tetrahedron: {c, b, 2, f} */ 3009 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3010 orntNew[0] = ornt[0]; 3011 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3012 orntNew[1] = 0; 3013 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3014 orntNew[2] = ornt[2]; 3015 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3016 orntNew[3] = ornt[3]; 3017 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3018 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3019 #if 1 3020 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); 3021 for (p = 0; p < 4; ++p) { 3022 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); 3023 } 3024 #endif 3025 /* D tetrahedron: {d, e, f, 3} */ 3026 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3027 orntNew[0] = 0; 3028 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3029 orntNew[1] = ornt[1]; 3030 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3031 orntNew[2] = ornt[2]; 3032 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3033 orntNew[3] = ornt[3]; 3034 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3035 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3036 #if 1 3037 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); 3038 for (p = 0; p < 4; ++p) { 3039 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); 3040 } 3041 #endif 3042 /* A' tetrahedron: {d, a, c, f} */ 3043 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3044 orntNew[0] = -3; 3045 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3046 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 3047 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3048 orntNew[2] = 0; 3049 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3050 orntNew[3] = 2; 3051 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3052 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3053 #if 1 3054 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); 3055 for (p = 0; p < 4; ++p) { 3056 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); 3057 } 3058 #endif 3059 /* B' tetrahedron: {e, b, a, f} */ 3060 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3061 orntNew[0] = -3; 3062 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3063 orntNew[1] = 1; 3064 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3065 orntNew[2] = 0; 3066 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 3067 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 3068 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3069 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3070 #if 1 3071 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); 3072 for (p = 0; p < 4; ++p) { 3073 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); 3074 } 3075 #endif 3076 /* C' tetrahedron: {b, f, c, a} */ 3077 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3078 orntNew[0] = -3; 3079 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 3080 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 3081 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3082 orntNew[2] = -3; 3083 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3084 orntNew[3] = -2; 3085 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3086 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3087 #if 1 3088 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); 3089 for (p = 0; p < 4; ++p) { 3090 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); 3091 } 3092 #endif 3093 /* D' tetrahedron: {f, e, d, a} */ 3094 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3095 orntNew[0] = -3; 3096 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3097 orntNew[1] = -3; 3098 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 3099 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 3100 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3101 orntNew[3] = -3; 3102 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3103 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3104 #if 1 3105 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); 3106 for (p = 0; p < 4; ++p) { 3107 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); 3108 } 3109 #endif 3110 } 3111 /* Hybrid cells have 5 faces */ 3112 for (c = cMax; c < cEnd; ++c) { 3113 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 3114 const PetscInt *cone, *ornt, *fornt; 3115 PetscInt coneNew[5], orntNew[5], o, of, i; 3116 3117 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3118 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3119 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 3120 o = ornt[0] < 0 ? -1 : 1; 3121 for (r = 0; r < 3; ++r) { 3122 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 3123 orntNew[0] = ornt[0]; 3124 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 3125 orntNew[1] = ornt[1]; 3126 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 3127 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 3128 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 3129 orntNew[i] = 0; 3130 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 3131 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 3132 orntNew[i] = 0; 3133 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 3134 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 3135 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); 3136 orntNew[i] = 0; 3137 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3138 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3139 #if 1 3140 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); 3141 for (p = 0; p < 2; ++p) { 3142 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); 3143 } 3144 for (p = 2; p < 5; ++p) { 3145 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); 3146 } 3147 #endif 3148 } 3149 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 3150 orntNew[0] = 0; 3151 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3152 orntNew[1] = 0; 3153 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3154 orntNew[2] = 0; 3155 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3156 orntNew[3] = 0; 3157 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3158 orntNew[4] = 0; 3159 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3160 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3161 #if 1 3162 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); 3163 for (p = 0; p < 2; ++p) { 3164 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); 3165 } 3166 for (p = 2; p < 5; ++p) { 3167 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); 3168 } 3169 #endif 3170 } 3171 /* Split faces have 3 edges and the same cells as the parent */ 3172 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3173 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3174 for (f = fStart; f < fMax; ++f) { 3175 const PetscInt newp = fStartNew + (f - fStart)*4; 3176 const PetscInt *cone, *ornt, *support; 3177 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3178 3179 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3180 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3181 /* A triangle */ 3182 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3183 orntNew[0] = ornt[0]; 3184 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3185 orntNew[1] = -2; 3186 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3187 orntNew[2] = ornt[2]; 3188 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3189 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3190 #if 1 3191 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); 3192 for (p = 0; p < 3; ++p) { 3193 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); 3194 } 3195 #endif 3196 /* B triangle */ 3197 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3198 orntNew[0] = ornt[0]; 3199 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3200 orntNew[1] = ornt[1]; 3201 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3202 orntNew[2] = -2; 3203 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3204 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3205 #if 1 3206 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); 3207 for (p = 0; p < 3; ++p) { 3208 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); 3209 } 3210 #endif 3211 /* C triangle */ 3212 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3213 orntNew[0] = -2; 3214 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3215 orntNew[1] = ornt[1]; 3216 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3217 orntNew[2] = ornt[2]; 3218 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3219 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3220 #if 1 3221 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); 3222 for (p = 0; p < 3; ++p) { 3223 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); 3224 } 3225 #endif 3226 /* D triangle */ 3227 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3228 orntNew[0] = 0; 3229 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3230 orntNew[1] = 0; 3231 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3232 orntNew[2] = 0; 3233 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3234 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3235 #if 1 3236 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); 3237 for (p = 0; p < 3; ++p) { 3238 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); 3239 } 3240 #endif 3241 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3242 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3243 for (r = 0; r < 4; ++r) { 3244 for (s = 0; s < supportSize; ++s) { 3245 PetscInt subf; 3246 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3247 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3248 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3249 for (c = 0; c < coneSize; ++c) { 3250 if (cone[c] == f) break; 3251 } 3252 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3253 if (support[s] < cMax) { 3254 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3255 } else { 3256 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3257 } 3258 } 3259 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3260 #if 1 3261 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); 3262 for (p = 0; p < supportSize; ++p) { 3263 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); 3264 } 3265 #endif 3266 } 3267 } 3268 /* Interior cell faces have 3 edges and 2 cells */ 3269 for (c = cStart; c < cMax; ++c) { 3270 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3271 const PetscInt *cone, *ornt; 3272 PetscInt coneNew[3], orntNew[3]; 3273 PetscInt supportNew[2]; 3274 3275 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3276 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3277 /* Face A: {c, a, d} */ 3278 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3279 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3280 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3281 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3282 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 3283 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3284 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3285 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3286 #if 1 3287 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3288 for (p = 0; p < 3; ++p) { 3289 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); 3290 } 3291 #endif 3292 supportNew[0] = (c - cStart)*8 + 0; 3293 supportNew[1] = (c - cStart)*8 + 0+4; 3294 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3295 #if 1 3296 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3297 for (p = 0; p < 2; ++p) { 3298 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); 3299 } 3300 #endif 3301 ++newp; 3302 /* Face B: {a, b, e} */ 3303 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3304 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3305 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 3306 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3307 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3308 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3309 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3310 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3311 #if 1 3312 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); 3313 for (p = 0; p < 3; ++p) { 3314 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); 3315 } 3316 #endif 3317 supportNew[0] = (c - cStart)*8 + 1; 3318 supportNew[1] = (c - cStart)*8 + 1+4; 3319 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3320 #if 1 3321 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3322 for (p = 0; p < 2; ++p) { 3323 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); 3324 } 3325 #endif 3326 ++newp; 3327 /* Face C: {c, f, b} */ 3328 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3329 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3330 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3331 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3332 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 3333 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3334 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3335 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3336 #if 1 3337 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3338 for (p = 0; p < 3; ++p) { 3339 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); 3340 } 3341 #endif 3342 supportNew[0] = (c - cStart)*8 + 2; 3343 supportNew[1] = (c - cStart)*8 + 2+4; 3344 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3345 #if 1 3346 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3347 for (p = 0; p < 2; ++p) { 3348 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); 3349 } 3350 #endif 3351 ++newp; 3352 /* Face D: {d, e, f} */ 3353 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 3354 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3355 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3356 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3357 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3358 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3359 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3360 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3361 #if 1 3362 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3363 for (p = 0; p < 3; ++p) { 3364 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); 3365 } 3366 #endif 3367 supportNew[0] = (c - cStart)*8 + 3; 3368 supportNew[1] = (c - cStart)*8 + 3+4; 3369 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3370 #if 1 3371 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3372 for (p = 0; p < 2; ++p) { 3373 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); 3374 } 3375 #endif 3376 ++newp; 3377 /* Face E: {d, f, a} */ 3378 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3379 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3380 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3381 orntNew[1] = -2; 3382 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3383 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3384 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3385 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3386 #if 1 3387 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3388 for (p = 0; p < 3; ++p) { 3389 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); 3390 } 3391 #endif 3392 supportNew[0] = (c - cStart)*8 + 0+4; 3393 supportNew[1] = (c - cStart)*8 + 3+4; 3394 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3395 #if 1 3396 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3397 for (p = 0; p < 2; ++p) { 3398 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); 3399 } 3400 #endif 3401 ++newp; 3402 /* Face F: {c, a, f} */ 3403 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3404 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3405 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3406 orntNew[1] = 0; 3407 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3408 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3409 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3410 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3411 #if 1 3412 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3413 for (p = 0; p < 3; ++p) { 3414 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); 3415 } 3416 #endif 3417 supportNew[0] = (c - cStart)*8 + 0+4; 3418 supportNew[1] = (c - cStart)*8 + 2+4; 3419 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3420 #if 1 3421 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3422 for (p = 0; p < 2; ++p) { 3423 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); 3424 } 3425 #endif 3426 ++newp; 3427 /* Face G: {e, a, f} */ 3428 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3429 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3430 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3431 orntNew[1] = 0; 3432 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3433 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3434 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3435 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3436 #if 1 3437 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3438 for (p = 0; p < 3; ++p) { 3439 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); 3440 } 3441 #endif 3442 supportNew[0] = (c - cStart)*8 + 1+4; 3443 supportNew[1] = (c - cStart)*8 + 3+4; 3444 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3445 #if 1 3446 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3447 for (p = 0; p < 2; ++p) { 3448 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); 3449 } 3450 #endif 3451 ++newp; 3452 /* Face H: {a, b, f} */ 3453 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3454 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3455 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3456 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3457 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3458 orntNew[2] = -2; 3459 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3460 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3461 #if 1 3462 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3463 for (p = 0; p < 3; ++p) { 3464 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); 3465 } 3466 #endif 3467 supportNew[0] = (c - cStart)*8 + 1+4; 3468 supportNew[1] = (c - cStart)*8 + 2+4; 3469 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3470 #if 1 3471 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3472 for (p = 0; p < 2; ++p) { 3473 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); 3474 } 3475 #endif 3476 ++newp; 3477 } 3478 /* Hybrid split faces have 4 edges and same cells */ 3479 for (f = fMax; f < fEnd; ++f) { 3480 const PetscInt *cone, *ornt, *support; 3481 PetscInt coneNew[4], orntNew[4]; 3482 PetscInt supportNew[2], size, s, c; 3483 3484 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3485 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3486 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3487 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3488 for (r = 0; r < 2; ++r) { 3489 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3490 3491 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3492 orntNew[0] = ornt[0]; 3493 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3494 orntNew[1] = ornt[1]; 3495 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3496 orntNew[2+r] = 0; 3497 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3498 orntNew[3-r] = 0; 3499 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3500 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3501 #if 1 3502 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3503 for (p = 0; p < 2; ++p) { 3504 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); 3505 } 3506 for (p = 2; p < 4; ++p) { 3507 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); 3508 } 3509 #endif 3510 for (s = 0; s < size; ++s) { 3511 const PetscInt *coneCell, *orntCell, *fornt; 3512 PetscInt o, of; 3513 3514 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3515 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3516 o = orntCell[0] < 0 ? -1 : 1; 3517 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3518 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3519 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3520 of = fornt[c-2] < 0 ? -1 : 1; 3521 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3522 } 3523 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3524 #if 1 3525 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3526 for (p = 0; p < size; ++p) { 3527 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); 3528 } 3529 #endif 3530 } 3531 } 3532 /* Hybrid cell faces have 4 edges and 2 cells */ 3533 for (c = cMax; c < cEnd; ++c) { 3534 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3535 const PetscInt *cone, *ornt; 3536 PetscInt coneNew[4], orntNew[4]; 3537 PetscInt supportNew[2]; 3538 3539 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3540 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3541 for (r = 0; r < 3; ++r) { 3542 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3543 orntNew[0] = 0; 3544 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3545 orntNew[1] = 0; 3546 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3547 orntNew[2] = 0; 3548 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3549 orntNew[3] = 0; 3550 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3551 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3552 #if 1 3553 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); 3554 for (p = 0; p < 2; ++p) { 3555 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); 3556 } 3557 for (p = 2; p < 4; ++p) { 3558 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); 3559 } 3560 #endif 3561 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3562 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3563 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3564 #if 1 3565 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); 3566 for (p = 0; p < 2; ++p) { 3567 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); 3568 } 3569 #endif 3570 } 3571 } 3572 /* Interior split edges have 2 vertices and the same faces as the parent */ 3573 for (e = eStart; e < eMax; ++e) { 3574 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3575 3576 for (r = 0; r < 2; ++r) { 3577 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3578 const PetscInt *cone, *ornt, *support; 3579 PetscInt coneNew[2], coneSize, c, supportSize, s; 3580 3581 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3582 coneNew[0] = vStartNew + (cone[0] - vStart); 3583 coneNew[1] = vStartNew + (cone[1] - vStart); 3584 coneNew[(r+1)%2] = newv; 3585 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3586 #if 1 3587 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3588 for (p = 0; p < 2; ++p) { 3589 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); 3590 } 3591 #endif 3592 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3593 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3594 for (s = 0; s < supportSize; ++s) { 3595 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3596 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3597 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3598 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3599 if (support[s] < fMax) { 3600 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3601 } else { 3602 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3603 } 3604 } 3605 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3606 #if 1 3607 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3608 for (p = 0; p < supportSize; ++p) { 3609 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); 3610 } 3611 #endif 3612 } 3613 } 3614 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3615 for (f = fStart; f < fMax; ++f) { 3616 const PetscInt *cone, *ornt, *support; 3617 PetscInt coneSize, supportSize, s; 3618 3619 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3620 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3621 for (r = 0; r < 3; ++r) { 3622 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3623 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3624 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3625 -1, -1, 1, 6, 0, 4, 3626 2, 5, 3, 4, -1, -1, 3627 -1, -1, 3, 6, 2, 7}; 3628 3629 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3630 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3631 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3632 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3633 #if 1 3634 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3635 for (p = 0; p < 2; ++p) { 3636 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); 3637 } 3638 #endif 3639 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3640 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3641 for (s = 0; s < supportSize; ++s) { 3642 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3643 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3644 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3645 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3646 if (support[s] < cMax) { 3647 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3648 er = GetTetSomethingInverse_Static(ornt[c], r); 3649 if (er == eint[c]) { 3650 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3651 } else { 3652 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3653 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3654 } 3655 } else { 3656 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 3657 } 3658 } 3659 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3660 #if 1 3661 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3662 for (p = 0; p < intFaces; ++p) { 3663 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); 3664 } 3665 #endif 3666 } 3667 } 3668 /* Interior cell edges have 2 vertices and 4 faces */ 3669 for (c = cStart; c < cMax; ++c) { 3670 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3671 const PetscInt *cone, *ornt, *fcone; 3672 PetscInt coneNew[2], supportNew[4], find; 3673 3674 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3675 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3676 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3677 find = GetTriEdge_Static(ornt[0], 0); 3678 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3679 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3680 find = GetTriEdge_Static(ornt[2], 1); 3681 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3682 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3683 #if 1 3684 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3685 for (p = 0; p < 2; ++p) { 3686 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); 3687 } 3688 #endif 3689 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3690 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3691 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3692 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3693 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3694 #if 1 3695 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3696 for (p = 0; p < 4; ++p) { 3697 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); 3698 } 3699 #endif 3700 } 3701 /* Hybrid edges have two vertices and the same faces */ 3702 for (e = eMax; e < eEnd; ++e) { 3703 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3704 const PetscInt *cone, *support, *fcone; 3705 PetscInt coneNew[2], size, fsize, s; 3706 3707 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3708 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3709 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3710 coneNew[0] = vStartNew + (cone[0] - vStart); 3711 coneNew[1] = vStartNew + (cone[1] - vStart); 3712 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3713 #if 1 3714 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3715 for (p = 0; p < 2; ++p) { 3716 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); 3717 } 3718 #endif 3719 for (s = 0; s < size; ++s) { 3720 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3721 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3722 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3723 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3724 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3725 } 3726 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3727 #if 1 3728 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3729 for (p = 0; p < size; ++p) { 3730 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); 3731 } 3732 #endif 3733 } 3734 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3735 for (f = fMax; f < fEnd; ++f) { 3736 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3737 const PetscInt *cone, *support, *ccone, *cornt; 3738 PetscInt coneNew[2], size, csize, s; 3739 3740 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3741 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3742 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3743 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3744 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3745 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3746 #if 1 3747 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3748 for (p = 0; p < 2; ++p) { 3749 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); 3750 } 3751 #endif 3752 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3753 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3754 for (s = 0; s < size; ++s) { 3755 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3756 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3757 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3758 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3759 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]); 3760 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 3761 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 3762 } 3763 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3764 #if 1 3765 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3766 for (p = 0; p < 2+size*2; ++p) { 3767 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); 3768 } 3769 #endif 3770 } 3771 /* Interior vertices have identical supports */ 3772 for (v = vStart; v < vEnd; ++v) { 3773 const PetscInt newp = vStartNew + (v - vStart); 3774 const PetscInt *support, *cone; 3775 PetscInt size, s; 3776 3777 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3778 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3779 for (s = 0; s < size; ++s) { 3780 PetscInt r = 0; 3781 3782 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3783 if (cone[1] == v) r = 1; 3784 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3785 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3786 } 3787 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3788 #if 1 3789 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3790 for (p = 0; p < size; ++p) { 3791 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); 3792 } 3793 #endif 3794 } 3795 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3796 for (e = eStart; e < eMax; ++e) { 3797 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3798 const PetscInt *cone, *support; 3799 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3800 3801 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3802 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3803 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3804 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3805 for (s = 0; s < size; ++s) { 3806 PetscInt r = 0; 3807 3808 if (support[s] < fMax) { 3809 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3810 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3811 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3812 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3813 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3814 faceSize += 2; 3815 } else { 3816 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3817 ++faceSize; 3818 } 3819 } 3820 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3821 for (s = 0; s < starSize*2; s += 2) { 3822 const PetscInt *cone, *ornt; 3823 PetscInt e01, e23; 3824 3825 if ((star[s] >= cStart) && (star[s] < cMax)) { 3826 /* Check edge 0-1 */ 3827 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3828 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3829 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3830 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3831 /* Check edge 2-3 */ 3832 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3833 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3834 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3835 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3836 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3837 } 3838 } 3839 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3840 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3841 #if 1 3842 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3843 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3844 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); 3845 } 3846 #endif 3847 } 3848 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3849 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3850 break; 3851 case REFINER_HEX_3D: 3852 /* 3853 Bottom (viewed from top) Top 3854 1---------2---------2 7---------2---------6 3855 | | | | | | 3856 | B 2 C | | H 2 G | 3857 | | | | | | 3858 3----3----0----1----1 3----3----0----1----1 3859 | | | | | | 3860 | A 0 D | | E 0 F | 3861 | | | | | | 3862 0---------0---------3 4---------0---------5 3863 */ 3864 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3865 for (c = cStart; c < cEnd; ++c) { 3866 const PetscInt newp = (c - cStart)*8; 3867 const PetscInt *cone, *ornt; 3868 PetscInt coneNew[6], orntNew[6]; 3869 3870 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3871 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3872 /* A hex */ 3873 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3874 orntNew[0] = ornt[0]; 3875 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3876 orntNew[1] = 0; 3877 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3878 orntNew[2] = ornt[2]; 3879 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3880 orntNew[3] = 0; 3881 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3882 orntNew[4] = 0; 3883 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3884 orntNew[5] = ornt[5]; 3885 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3886 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3887 #if 1 3888 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); 3889 for (p = 0; p < 6; ++p) { 3890 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); 3891 } 3892 #endif 3893 /* B hex */ 3894 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3895 orntNew[0] = ornt[0]; 3896 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3897 orntNew[1] = 0; 3898 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3899 orntNew[2] = -1; 3900 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3901 orntNew[3] = ornt[3]; 3902 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3903 orntNew[4] = 0; 3904 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3905 orntNew[5] = ornt[5]; 3906 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3907 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3908 #if 1 3909 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); 3910 for (p = 0; p < 6; ++p) { 3911 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); 3912 } 3913 #endif 3914 /* C hex */ 3915 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3916 orntNew[0] = ornt[0]; 3917 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3918 orntNew[1] = 0; 3919 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3920 orntNew[2] = -1; 3921 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3922 orntNew[3] = ornt[3]; 3923 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3924 orntNew[4] = ornt[4]; 3925 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3926 orntNew[5] = -4; 3927 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3928 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3929 #if 1 3930 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); 3931 for (p = 0; p < 6; ++p) { 3932 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); 3933 } 3934 #endif 3935 /* D hex */ 3936 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3937 orntNew[0] = ornt[0]; 3938 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3939 orntNew[1] = 0; 3940 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3941 orntNew[2] = ornt[2]; 3942 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3943 orntNew[3] = 0; 3944 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3945 orntNew[4] = ornt[4]; 3946 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3947 orntNew[5] = -4; 3948 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3949 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3950 #if 1 3951 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); 3952 for (p = 0; p < 6; ++p) { 3953 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); 3954 } 3955 #endif 3956 /* E hex */ 3957 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3958 orntNew[0] = -4; 3959 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3960 orntNew[1] = ornt[1]; 3961 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3962 orntNew[2] = ornt[2]; 3963 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3964 orntNew[3] = 0; 3965 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3966 orntNew[4] = -1; 3967 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3968 orntNew[5] = ornt[5]; 3969 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3970 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3971 #if 1 3972 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); 3973 for (p = 0; p < 6; ++p) { 3974 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); 3975 } 3976 #endif 3977 /* F hex */ 3978 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3979 orntNew[0] = -4; 3980 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3981 orntNew[1] = ornt[1]; 3982 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3983 orntNew[2] = ornt[2]; 3984 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3985 orntNew[3] = -1; 3986 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3987 orntNew[4] = ornt[4]; 3988 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3989 orntNew[5] = 1; 3990 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3991 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3992 #if 1 3993 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); 3994 for (p = 0; p < 6; ++p) { 3995 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); 3996 } 3997 #endif 3998 /* G hex */ 3999 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4000 orntNew[0] = -4; 4001 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4002 orntNew[1] = ornt[1]; 4003 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4004 orntNew[2] = 0; 4005 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4006 orntNew[3] = ornt[3]; 4007 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4008 orntNew[4] = ornt[4]; 4009 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4010 orntNew[5] = -3; 4011 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4012 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4013 #if 1 4014 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); 4015 for (p = 0; p < 6; ++p) { 4016 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); 4017 } 4018 #endif 4019 /* H hex */ 4020 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4021 orntNew[0] = -4; 4022 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4023 orntNew[1] = ornt[1]; 4024 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4025 orntNew[2] = -1; 4026 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4027 orntNew[3] = ornt[3]; 4028 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4029 orntNew[4] = 3; 4030 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4031 orntNew[5] = ornt[5]; 4032 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4033 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4034 #if 1 4035 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); 4036 for (p = 0; p < 6; ++p) { 4037 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); 4038 } 4039 #endif 4040 } 4041 /* Split faces have 4 edges and the same cells as the parent */ 4042 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4043 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4044 for (f = fStart; f < fEnd; ++f) { 4045 for (r = 0; r < 4; ++r) { 4046 /* TODO: This can come from GetFaces_Internal() */ 4047 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}; 4048 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4049 const PetscInt *cone, *ornt, *support; 4050 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4051 4052 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4053 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4054 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4055 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4056 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4057 orntNew[(r+0)%4] = ornt[r]; 4058 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4059 orntNew[(r+1)%4] = 0; 4060 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4061 orntNew[(r+2)%4] = -2; 4062 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4063 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4064 #if 1 4065 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4066 for (p = 0; p < 4; ++p) { 4067 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); 4068 } 4069 #endif 4070 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4071 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4072 for (s = 0; s < supportSize; ++s) { 4073 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4074 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4075 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4076 for (c = 0; c < coneSize; ++c) { 4077 if (cone[c] == f) break; 4078 } 4079 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 4080 } 4081 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4082 #if 1 4083 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4084 for (p = 0; p < supportSize; ++p) { 4085 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); 4086 } 4087 #endif 4088 } 4089 } 4090 /* Interior faces have 4 edges and 2 cells */ 4091 for (c = cStart; c < cEnd; ++c) { 4092 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}; 4093 const PetscInt *cone, *ornt; 4094 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4095 4096 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4097 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4098 /* A-D face */ 4099 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 4100 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4101 orntNew[0] = 0; 4102 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4103 orntNew[1] = 0; 4104 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4105 orntNew[2] = -2; 4106 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4107 orntNew[3] = -2; 4108 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4109 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4110 #if 1 4111 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4112 for (p = 0; p < 4; ++p) { 4113 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); 4114 } 4115 #endif 4116 /* C-D face */ 4117 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 4118 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4119 orntNew[0] = 0; 4120 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4121 orntNew[1] = 0; 4122 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4123 orntNew[2] = -2; 4124 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4125 orntNew[3] = -2; 4126 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4127 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4128 #if 1 4129 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4130 for (p = 0; p < 4; ++p) { 4131 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); 4132 } 4133 #endif 4134 /* B-C face */ 4135 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 4136 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4137 orntNew[0] = -2; 4138 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4139 orntNew[1] = 0; 4140 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4141 orntNew[2] = 0; 4142 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4143 orntNew[3] = -2; 4144 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4145 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4146 #if 1 4147 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4148 for (p = 0; p < 4; ++p) { 4149 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); 4150 } 4151 #endif 4152 /* A-B face */ 4153 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 4154 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4155 orntNew[0] = -2; 4156 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4157 orntNew[1] = 0; 4158 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4159 orntNew[2] = 0; 4160 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4161 orntNew[3] = -2; 4162 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4163 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4164 #if 1 4165 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4166 for (p = 0; p < 4; ++p) { 4167 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); 4168 } 4169 #endif 4170 /* E-F face */ 4171 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 4172 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4173 orntNew[0] = -2; 4174 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4175 orntNew[1] = -2; 4176 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4177 orntNew[2] = 0; 4178 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4179 orntNew[3] = 0; 4180 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4181 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4182 #if 1 4183 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4184 for (p = 0; p < 4; ++p) { 4185 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); 4186 } 4187 #endif 4188 /* F-G face */ 4189 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 4190 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4191 orntNew[0] = -2; 4192 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4193 orntNew[1] = -2; 4194 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4195 orntNew[2] = 0; 4196 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4197 orntNew[3] = 0; 4198 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4199 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4200 #if 1 4201 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4202 for (p = 0; p < 4; ++p) { 4203 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); 4204 } 4205 #endif 4206 /* G-H face */ 4207 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 4208 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4209 orntNew[0] = -2; 4210 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4211 orntNew[1] = 0; 4212 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4213 orntNew[2] = 0; 4214 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4215 orntNew[3] = -2; 4216 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4217 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4218 #if 1 4219 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4220 for (p = 0; p < 4; ++p) { 4221 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); 4222 } 4223 #endif 4224 /* E-H face */ 4225 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 4226 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4227 orntNew[0] = -2; 4228 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4229 orntNew[1] = -2; 4230 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4231 orntNew[2] = 0; 4232 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4233 orntNew[3] = 0; 4234 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4235 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4236 #if 1 4237 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4238 for (p = 0; p < 4; ++p) { 4239 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); 4240 } 4241 #endif 4242 /* A-E face */ 4243 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 4244 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4245 orntNew[0] = 0; 4246 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4247 orntNew[1] = 0; 4248 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4249 orntNew[2] = -2; 4250 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4251 orntNew[3] = -2; 4252 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4253 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4254 #if 1 4255 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4256 for (p = 0; p < 4; ++p) { 4257 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); 4258 } 4259 #endif 4260 /* D-F face */ 4261 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 4262 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4263 orntNew[0] = -2; 4264 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4265 orntNew[1] = 0; 4266 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4267 orntNew[2] = 0; 4268 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4269 orntNew[3] = -2; 4270 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4271 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4272 #if 1 4273 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4274 for (p = 0; p < 4; ++p) { 4275 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); 4276 } 4277 #endif 4278 /* C-G face */ 4279 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 4280 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4281 orntNew[0] = -2; 4282 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4283 orntNew[1] = -2; 4284 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4285 orntNew[2] = 0; 4286 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4287 orntNew[3] = 0; 4288 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4289 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4290 #if 1 4291 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4292 for (p = 0; p < 4; ++p) { 4293 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); 4294 } 4295 #endif 4296 /* B-H face */ 4297 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 4298 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4299 orntNew[0] = 0; 4300 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4301 orntNew[1] = -2; 4302 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4303 orntNew[2] = -2; 4304 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4305 orntNew[3] = 0; 4306 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4307 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4308 #if 1 4309 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4310 for (p = 0; p < 4; ++p) { 4311 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); 4312 } 4313 #endif 4314 for (r = 0; r < 12; ++r) { 4315 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 4316 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4317 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4318 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4319 #if 1 4320 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4321 for (p = 0; p < 2; ++p) { 4322 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); 4323 } 4324 #endif 4325 } 4326 } 4327 /* Split edges have 2 vertices and the same faces as the parent */ 4328 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4329 for (e = eStart; e < eEnd; ++e) { 4330 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4331 4332 for (r = 0; r < 2; ++r) { 4333 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4334 const PetscInt *cone, *ornt, *support; 4335 PetscInt coneNew[2], coneSize, c, supportSize, s; 4336 4337 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4338 coneNew[0] = vStartNew + (cone[0] - vStart); 4339 coneNew[1] = vStartNew + (cone[1] - vStart); 4340 coneNew[(r+1)%2] = newv; 4341 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4342 #if 1 4343 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4344 for (p = 0; p < 2; ++p) { 4345 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); 4346 } 4347 #endif 4348 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4349 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4350 for (s = 0; s < supportSize; ++s) { 4351 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4352 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4353 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4354 for (c = 0; c < coneSize; ++c) { 4355 if (cone[c] == e) break; 4356 } 4357 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 4358 } 4359 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4360 #if 1 4361 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4362 for (p = 0; p < supportSize; ++p) { 4363 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); 4364 } 4365 #endif 4366 } 4367 } 4368 /* Face edges have 2 vertices and 2+cells faces */ 4369 for (f = fStart; f < fEnd; ++f) { 4370 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}; 4371 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4372 const PetscInt *cone, *coneCell, *orntCell, *support; 4373 PetscInt coneNew[2], coneSize, c, supportSize, s; 4374 4375 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4376 for (r = 0; r < 4; ++r) { 4377 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4378 4379 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4380 coneNew[1] = newv; 4381 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4382 #if 1 4383 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4384 for (p = 0; p < 2; ++p) { 4385 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); 4386 } 4387 #endif 4388 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4389 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4390 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4391 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4392 for (s = 0; s < supportSize; ++s) { 4393 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4394 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4395 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4396 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4397 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4398 } 4399 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4400 #if 1 4401 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4402 for (p = 0; p < 2+supportSize; ++p) { 4403 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); 4404 } 4405 #endif 4406 } 4407 } 4408 /* Cell edges have 2 vertices and 4 faces */ 4409 for (c = cStart; c < cEnd; ++c) { 4410 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}; 4411 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4412 const PetscInt *cone; 4413 PetscInt coneNew[2], supportNew[4]; 4414 4415 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4416 for (r = 0; r < 6; ++r) { 4417 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4418 4419 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4420 coneNew[1] = newv; 4421 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4422 #if 1 4423 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4424 for (p = 0; p < 2; ++p) { 4425 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); 4426 } 4427 #endif 4428 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4429 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4430 #if 1 4431 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4432 for (p = 0; p < 4; ++p) { 4433 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); 4434 } 4435 #endif 4436 } 4437 } 4438 /* Old vertices have identical supports */ 4439 for (v = vStart; v < vEnd; ++v) { 4440 const PetscInt newp = vStartNew + (v - vStart); 4441 const PetscInt *support, *cone; 4442 PetscInt size, s; 4443 4444 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4445 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4446 for (s = 0; s < size; ++s) { 4447 PetscInt r = 0; 4448 4449 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4450 if (cone[1] == v) r = 1; 4451 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4452 } 4453 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4454 #if 1 4455 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4456 for (p = 0; p < size; ++p) { 4457 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); 4458 } 4459 #endif 4460 } 4461 /* Edge vertices have 2 + faces supports */ 4462 for (e = eStart; e < eEnd; ++e) { 4463 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4464 const PetscInt *cone, *support; 4465 PetscInt size, s; 4466 4467 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4468 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4469 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4470 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4471 for (s = 0; s < size; ++s) { 4472 PetscInt r; 4473 4474 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4475 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4476 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 4477 } 4478 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4479 #if 1 4480 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4481 for (p = 0; p < 2+size; ++p) { 4482 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); 4483 } 4484 #endif 4485 } 4486 /* Face vertices have 4 + cells supports */ 4487 for (f = fStart; f < fEnd; ++f) { 4488 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4489 const PetscInt *cone, *support; 4490 PetscInt size, s; 4491 4492 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4493 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4494 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4495 for (s = 0; s < size; ++s) { 4496 PetscInt r; 4497 4498 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4499 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4500 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 4501 } 4502 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4503 #if 1 4504 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4505 for (p = 0; p < 4+size; ++p) { 4506 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); 4507 } 4508 #endif 4509 } 4510 /* Cell vertices have 6 supports */ 4511 for (c = cStart; c < cEnd; ++c) { 4512 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4513 PetscInt supportNew[6]; 4514 4515 for (r = 0; r < 6; ++r) { 4516 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4517 } 4518 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4519 } 4520 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4521 break; 4522 case REFINER_HYBRID_HEX_3D: 4523 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4524 /* 4525 Bottom (viewed from top) Top 4526 1---------2---------2 7---------2---------6 4527 | | | | | | 4528 | B 2 C | | H 2 G | 4529 | | | | | | 4530 3----3----0----1----1 3----3----0----1----1 4531 | | | | | | 4532 | A 0 D | | E 0 F | 4533 | | | | | | 4534 0---------0---------3 4---------0---------5 4535 */ 4536 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4537 for (c = cStart; c < cMax; ++c) { 4538 const PetscInt newp = (c - cStart)*8; 4539 const PetscInt *cone, *ornt; 4540 PetscInt coneNew[6], orntNew[6]; 4541 4542 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4543 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4544 /* A hex */ 4545 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4546 orntNew[0] = ornt[0]; 4547 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4548 orntNew[1] = 0; 4549 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4550 orntNew[2] = ornt[2]; 4551 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4552 orntNew[3] = 0; 4553 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4554 orntNew[4] = 0; 4555 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4556 orntNew[5] = ornt[5]; 4557 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4558 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4559 #if 1 4560 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); 4561 for (p = 0; p < 6; ++p) { 4562 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); 4563 } 4564 #endif 4565 /* B hex */ 4566 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4567 orntNew[0] = ornt[0]; 4568 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4569 orntNew[1] = 0; 4570 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4571 orntNew[2] = -1; 4572 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4573 orntNew[3] = ornt[3]; 4574 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4575 orntNew[4] = 0; 4576 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4577 orntNew[5] = ornt[5]; 4578 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4579 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4580 #if 1 4581 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); 4582 for (p = 0; p < 6; ++p) { 4583 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); 4584 } 4585 #endif 4586 /* C hex */ 4587 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4588 orntNew[0] = ornt[0]; 4589 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4590 orntNew[1] = 0; 4591 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4592 orntNew[2] = -1; 4593 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4594 orntNew[3] = ornt[3]; 4595 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4596 orntNew[4] = ornt[4]; 4597 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4598 orntNew[5] = -4; 4599 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4600 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4601 #if 1 4602 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); 4603 for (p = 0; p < 6; ++p) { 4604 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); 4605 } 4606 #endif 4607 /* D hex */ 4608 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4609 orntNew[0] = ornt[0]; 4610 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4611 orntNew[1] = 0; 4612 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4613 orntNew[2] = ornt[2]; 4614 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4615 orntNew[3] = 0; 4616 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4617 orntNew[4] = ornt[4]; 4618 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4619 orntNew[5] = -4; 4620 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4621 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4622 #if 1 4623 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); 4624 for (p = 0; p < 6; ++p) { 4625 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); 4626 } 4627 #endif 4628 /* E hex */ 4629 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4630 orntNew[0] = -4; 4631 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4632 orntNew[1] = ornt[1]; 4633 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4634 orntNew[2] = ornt[2]; 4635 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4636 orntNew[3] = 0; 4637 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4638 orntNew[4] = -1; 4639 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4640 orntNew[5] = ornt[5]; 4641 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4642 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4643 #if 1 4644 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); 4645 for (p = 0; p < 6; ++p) { 4646 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); 4647 } 4648 #endif 4649 /* F hex */ 4650 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4651 orntNew[0] = -4; 4652 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4653 orntNew[1] = ornt[1]; 4654 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4655 orntNew[2] = ornt[2]; 4656 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4657 orntNew[3] = -1; 4658 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4659 orntNew[4] = ornt[4]; 4660 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4661 orntNew[5] = 1; 4662 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4663 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4664 #if 1 4665 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); 4666 for (p = 0; p < 6; ++p) { 4667 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); 4668 } 4669 #endif 4670 /* G hex */ 4671 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4672 orntNew[0] = -4; 4673 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4674 orntNew[1] = ornt[1]; 4675 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4676 orntNew[2] = 0; 4677 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4678 orntNew[3] = ornt[3]; 4679 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4680 orntNew[4] = ornt[4]; 4681 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4682 orntNew[5] = -3; 4683 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4684 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4685 #if 1 4686 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); 4687 for (p = 0; p < 6; ++p) { 4688 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); 4689 } 4690 #endif 4691 /* H hex */ 4692 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4693 orntNew[0] = -4; 4694 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4695 orntNew[1] = ornt[1]; 4696 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4697 orntNew[2] = -1; 4698 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4699 orntNew[3] = ornt[3]; 4700 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4701 orntNew[4] = 3; 4702 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4703 orntNew[5] = ornt[5]; 4704 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4705 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4706 #if 1 4707 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); 4708 for (p = 0; p < 6; ++p) { 4709 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); 4710 } 4711 #endif 4712 } 4713 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4714 /* 4715 3---------2---------2 4716 | | | 4717 | D 2 C | 4718 | | | 4719 3----3----0----1----1 4720 | | | 4721 | A 0 B | 4722 | | | 4723 0---------0---------1 4724 */ 4725 for (c = cMax; c < cEnd; ++c) { 4726 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4727 const PetscInt *cone, *ornt, *fornt; 4728 PetscInt coneNew[6], orntNew[6], o, of, i; 4729 4730 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4731 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4732 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4733 o = ornt[0] < 0 ? -1 : 1; 4734 for (r = 0; r < 4; ++r) { 4735 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4736 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4737 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 4738 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]); 4739 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4740 orntNew[0] = ornt[0]; 4741 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4742 orntNew[1] = ornt[0]; 4743 of = fornt[edgeA] < 0 ? -1 : 1; 4744 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 4745 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 4746 orntNew[i] = ornt[edgeA]; 4747 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 4748 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4749 orntNew[i] = 0; 4750 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 4751 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4752 orntNew[i] = -2; 4753 of = fornt[edgeB] < 0 ? -1 : 1; 4754 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 4755 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 4756 orntNew[i] = ornt[edgeB]; 4757 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4758 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4759 #if 1 4760 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); 4761 for (p = 0; p < 2; ++p) { 4762 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); 4763 } 4764 for (p = 2; p < 6; ++p) { 4765 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); 4766 } 4767 #endif 4768 } 4769 } 4770 /* Interior split faces have 4 edges and the same cells as the parent */ 4771 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4772 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4773 for (f = fStart; f < fMax; ++f) { 4774 for (r = 0; r < 4; ++r) { 4775 /* TODO: This can come from GetFaces_Internal() */ 4776 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}; 4777 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4778 const PetscInt *cone, *ornt, *support; 4779 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4780 4781 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4782 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4783 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4784 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4785 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4786 orntNew[(r+0)%4] = ornt[r]; 4787 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4788 orntNew[(r+1)%4] = 0; 4789 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4790 orntNew[(r+2)%4] = -2; 4791 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4792 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4793 #if 1 4794 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4795 for (p = 0; p < 4; ++p) { 4796 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); 4797 } 4798 #endif 4799 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4800 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4801 for (s = 0; s < supportSize; ++s) { 4802 PetscInt subf; 4803 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4804 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4805 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4806 for (c = 0; c < coneSize; ++c) { 4807 if (cone[c] == f) break; 4808 } 4809 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4810 if (support[s] < cMax) { 4811 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4812 } else { 4813 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4814 } 4815 } 4816 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4817 #if 1 4818 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4819 for (p = 0; p < supportSize; ++p) { 4820 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); 4821 } 4822 #endif 4823 } 4824 } 4825 /* Interior cell faces have 4 edges and 2 cells */ 4826 for (c = cStart; c < cMax; ++c) { 4827 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}; 4828 const PetscInt *cone, *ornt; 4829 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4830 4831 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4832 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4833 /* A-D face */ 4834 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4835 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4836 orntNew[0] = 0; 4837 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4838 orntNew[1] = 0; 4839 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4840 orntNew[2] = -2; 4841 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4842 orntNew[3] = -2; 4843 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4844 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4845 #if 1 4846 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4847 for (p = 0; p < 4; ++p) { 4848 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); 4849 } 4850 #endif 4851 /* C-D face */ 4852 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4853 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4854 orntNew[0] = 0; 4855 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4856 orntNew[1] = 0; 4857 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4858 orntNew[2] = -2; 4859 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4860 orntNew[3] = -2; 4861 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4862 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4863 #if 1 4864 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4865 for (p = 0; p < 4; ++p) { 4866 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); 4867 } 4868 #endif 4869 /* B-C face */ 4870 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4871 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4872 orntNew[0] = -2; 4873 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4874 orntNew[1] = 0; 4875 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4876 orntNew[2] = 0; 4877 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4878 orntNew[3] = -2; 4879 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4880 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4881 #if 1 4882 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4883 for (p = 0; p < 4; ++p) { 4884 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); 4885 } 4886 #endif 4887 /* A-B face */ 4888 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4889 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4890 orntNew[0] = -2; 4891 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4892 orntNew[1] = 0; 4893 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4894 orntNew[2] = 0; 4895 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4896 orntNew[3] = -2; 4897 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4898 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4899 #if 1 4900 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4901 for (p = 0; p < 4; ++p) { 4902 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); 4903 } 4904 #endif 4905 /* E-F face */ 4906 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4907 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4908 orntNew[0] = -2; 4909 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4910 orntNew[1] = -2; 4911 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4912 orntNew[2] = 0; 4913 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4914 orntNew[3] = 0; 4915 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4916 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4917 #if 1 4918 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4919 for (p = 0; p < 4; ++p) { 4920 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); 4921 } 4922 #endif 4923 /* F-G face */ 4924 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4925 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4926 orntNew[0] = -2; 4927 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4928 orntNew[1] = -2; 4929 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4930 orntNew[2] = 0; 4931 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4932 orntNew[3] = 0; 4933 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4934 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4935 #if 1 4936 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4937 for (p = 0; p < 4; ++p) { 4938 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4939 } 4940 #endif 4941 /* G-H face */ 4942 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4943 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4944 orntNew[0] = -2; 4945 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4946 orntNew[1] = 0; 4947 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4948 orntNew[2] = 0; 4949 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4950 orntNew[3] = -2; 4951 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4952 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4953 #if 1 4954 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4955 for (p = 0; p < 4; ++p) { 4956 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); 4957 } 4958 #endif 4959 /* E-H face */ 4960 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4961 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4962 orntNew[0] = -2; 4963 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4964 orntNew[1] = -2; 4965 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4966 orntNew[2] = 0; 4967 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4968 orntNew[3] = 0; 4969 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4970 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4971 #if 1 4972 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4973 for (p = 0; p < 4; ++p) { 4974 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); 4975 } 4976 #endif 4977 /* A-E face */ 4978 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4979 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4980 orntNew[0] = 0; 4981 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4982 orntNew[1] = 0; 4983 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4984 orntNew[2] = -2; 4985 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4986 orntNew[3] = -2; 4987 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4988 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4989 #if 1 4990 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4991 for (p = 0; p < 4; ++p) { 4992 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); 4993 } 4994 #endif 4995 /* D-F face */ 4996 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4997 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4998 orntNew[0] = -2; 4999 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 5000 orntNew[1] = 0; 5001 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5002 orntNew[2] = 0; 5003 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5004 orntNew[3] = -2; 5005 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5006 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5007 #if 1 5008 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5009 for (p = 0; p < 4; ++p) { 5010 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); 5011 } 5012 #endif 5013 /* C-G face */ 5014 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 5015 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5016 orntNew[0] = -2; 5017 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 5018 orntNew[1] = -2; 5019 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 5020 orntNew[2] = 0; 5021 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5022 orntNew[3] = 0; 5023 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5024 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5025 #if 1 5026 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5027 for (p = 0; p < 4; ++p) { 5028 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); 5029 } 5030 #endif 5031 /* B-H face */ 5032 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 5033 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5034 orntNew[0] = 0; 5035 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5036 orntNew[1] = -2; 5037 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 5038 orntNew[2] = -2; 5039 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 5040 orntNew[3] = 0; 5041 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5042 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5043 #if 1 5044 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5045 for (p = 0; p < 4; ++p) { 5046 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); 5047 } 5048 #endif 5049 for (r = 0; r < 12; ++r) { 5050 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 5051 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 5052 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 5053 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5054 #if 1 5055 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5056 for (p = 0; p < 2; ++p) { 5057 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); 5058 } 5059 #endif 5060 } 5061 } 5062 /* Hybrid split faces have 4 edges and same cells */ 5063 for (f = fMax; f < fEnd; ++f) { 5064 const PetscInt *cone, *ornt, *support; 5065 PetscInt coneNew[4], orntNew[4]; 5066 PetscInt supportNew[2], size, s, c; 5067 5068 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5069 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5070 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5071 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5072 for (r = 0; r < 2; ++r) { 5073 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 5074 5075 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 5076 orntNew[0] = ornt[0]; 5077 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 5078 orntNew[1] = ornt[1]; 5079 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 5080 orntNew[2+r] = 0; 5081 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5082 orntNew[3-r] = 0; 5083 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5084 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5085 #if 1 5086 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 5087 for (p = 0; p < 2; ++p) { 5088 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); 5089 } 5090 for (p = 2; p < 4; ++p) { 5091 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); 5092 } 5093 #endif 5094 for (s = 0; s < size; ++s) { 5095 const PetscInt *coneCell, *orntCell, *fornt; 5096 PetscInt o, of; 5097 5098 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5099 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5100 o = orntCell[0] < 0 ? -1 : 1; 5101 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 5102 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 5103 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 5104 of = fornt[c-2] < 0 ? -1 : 1; 5105 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 5106 } 5107 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5108 #if 1 5109 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 5110 for (p = 0; p < size; ++p) { 5111 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); 5112 } 5113 #endif 5114 } 5115 } 5116 /* Hybrid cell faces have 4 edges and 2 cells */ 5117 for (c = cMax; c < cEnd; ++c) { 5118 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 5119 const PetscInt *cone, *ornt; 5120 PetscInt coneNew[4], orntNew[4]; 5121 PetscInt supportNew[2]; 5122 5123 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5124 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5125 for (r = 0; r < 4; ++r) { 5126 #if 0 5127 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 5128 orntNew[0] = 0; 5129 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 5130 orntNew[1] = 0; 5131 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 5132 orntNew[2] = 0; 5133 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5134 orntNew[3] = 0; 5135 #else 5136 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 5137 orntNew[0] = 0; 5138 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 5139 orntNew[1] = 0; 5140 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 5141 orntNew[2] = 0; 5142 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5143 orntNew[3] = 0; 5144 #endif 5145 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 5146 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 5147 #if 1 5148 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); 5149 for (p = 0; p < 2; ++p) { 5150 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); 5151 } 5152 for (p = 2; p < 4; ++p) { 5153 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); 5154 } 5155 #endif 5156 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 5157 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 5158 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 5159 #if 1 5160 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); 5161 for (p = 0; p < 2; ++p) { 5162 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); 5163 } 5164 #endif 5165 } 5166 } 5167 /* Interior split edges have 2 vertices and the same faces as the parent */ 5168 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5169 for (e = eStart; e < eMax; ++e) { 5170 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5171 5172 for (r = 0; r < 2; ++r) { 5173 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5174 const PetscInt *cone, *ornt, *support; 5175 PetscInt coneNew[2], coneSize, c, supportSize, s; 5176 5177 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5178 coneNew[0] = vStartNew + (cone[0] - vStart); 5179 coneNew[1] = vStartNew + (cone[1] - vStart); 5180 coneNew[(r+1)%2] = newv; 5181 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5182 #if 1 5183 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5184 for (p = 0; p < 2; ++p) { 5185 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); 5186 } 5187 #endif 5188 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5189 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5190 for (s = 0; s < supportSize; ++s) { 5191 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5192 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5193 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5194 for (c = 0; c < coneSize; ++c) { 5195 if (cone[c] == e) break; 5196 } 5197 if (support[s] < fMax) { 5198 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 5199 } else { 5200 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 5201 } 5202 } 5203 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5204 #if 1 5205 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5206 for (p = 0; p < supportSize; ++p) { 5207 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); 5208 } 5209 #endif 5210 } 5211 } 5212 /* Interior face edges have 2 vertices and 2+cells faces */ 5213 for (f = fStart; f < fMax; ++f) { 5214 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}; 5215 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5216 const PetscInt *cone, *coneCell, *orntCell, *support; 5217 PetscInt coneNew[2], coneSize, c, supportSize, s; 5218 5219 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5220 for (r = 0; r < 4; ++r) { 5221 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5222 5223 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5224 coneNew[1] = newv; 5225 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5226 #if 1 5227 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5228 for (p = 0; p < 2; ++p) { 5229 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); 5230 } 5231 #endif 5232 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5233 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5234 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5235 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5236 for (s = 0; s < supportSize; ++s) { 5237 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5238 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5239 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5240 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5241 if (support[s] < cMax) { 5242 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5243 } else { 5244 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 5245 } 5246 } 5247 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5248 #if 1 5249 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5250 for (p = 0; p < 2+supportSize; ++p) { 5251 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); 5252 } 5253 #endif 5254 } 5255 } 5256 /* Interior cell edges have 2 vertices and 4 faces */ 5257 for (c = cStart; c < cMax; ++c) { 5258 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}; 5259 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5260 const PetscInt *cone; 5261 PetscInt coneNew[2], supportNew[4]; 5262 5263 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5264 for (r = 0; r < 6; ++r) { 5265 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5266 5267 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5268 coneNew[1] = newv; 5269 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5270 #if 1 5271 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 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 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5277 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5278 #if 1 5279 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5280 for (p = 0; p < 4; ++p) { 5281 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); 5282 } 5283 #endif 5284 } 5285 } 5286 /* Hybrid edges have two vertices and the same faces */ 5287 for (e = eMax; e < eEnd; ++e) { 5288 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5289 const PetscInt *cone, *support, *fcone; 5290 PetscInt coneNew[2], size, fsize, s; 5291 5292 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5293 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5294 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5295 coneNew[0] = vStartNew + (cone[0] - vStart); 5296 coneNew[1] = vStartNew + (cone[1] - vStart); 5297 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5298 #if 1 5299 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5300 for (p = 0; p < 2; ++p) { 5301 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); 5302 } 5303 #endif 5304 for (s = 0; s < size; ++s) { 5305 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5306 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5307 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5308 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5309 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 5310 } 5311 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5312 #if 1 5313 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5314 for (p = 0; p < size; ++p) { 5315 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); 5316 } 5317 #endif 5318 } 5319 /* Hybrid face edges have 2 vertices and 2+cells faces */ 5320 for (f = fMax; f < fEnd; ++f) { 5321 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5322 const PetscInt *cone, *support, *ccone, *cornt; 5323 PetscInt coneNew[2], size, csize, s; 5324 5325 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5326 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5327 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5328 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5329 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 5330 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5331 #if 1 5332 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5333 for (p = 0; p < 2; ++p) { 5334 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); 5335 } 5336 #endif 5337 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 5338 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5339 for (s = 0; s < size; ++s) { 5340 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5341 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5342 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5343 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5344 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]); 5345 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 5346 } 5347 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5348 #if 1 5349 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5350 for (p = 0; p < 2+size; ++p) { 5351 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); 5352 } 5353 #endif 5354 } 5355 /* Hybrid cell edges have 2 vertices and 4 faces */ 5356 for (c = cMax; c < cEnd; ++c) { 5357 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5358 const PetscInt *cone, *support; 5359 PetscInt coneNew[2], size; 5360 5361 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5362 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5363 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5364 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5365 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5366 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5367 #if 1 5368 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5369 for (p = 0; p < 2; ++p) { 5370 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); 5371 } 5372 #endif 5373 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5374 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5375 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5376 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5377 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5378 #if 1 5379 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5380 for (p = 0; p < 4; ++p) { 5381 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); 5382 } 5383 #endif 5384 } 5385 /* Interior vertices have identical supports */ 5386 for (v = vStart; v < vEnd; ++v) { 5387 const PetscInt newp = vStartNew + (v - vStart); 5388 const PetscInt *support, *cone; 5389 PetscInt size, s; 5390 5391 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5392 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5393 for (s = 0; s < size; ++s) { 5394 PetscInt r = 0; 5395 5396 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5397 if (cone[1] == v) r = 1; 5398 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5399 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5400 } 5401 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5402 #if 1 5403 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5404 for (p = 0; p < size; ++p) { 5405 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 5406 } 5407 #endif 5408 } 5409 /* Interior edge vertices have 2 + faces supports */ 5410 for (e = eStart; e < eMax; ++e) { 5411 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5412 const PetscInt *cone, *support; 5413 PetscInt size, s; 5414 5415 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5416 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5417 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5418 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5419 for (s = 0; s < size; ++s) { 5420 PetscInt r; 5421 5422 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5423 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5424 if (support[s] < fMax) { 5425 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5426 } else { 5427 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5428 } 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 < 2+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 /* Interior face vertices have 4 + cells supports */ 5439 for (f = fStart; f < fMax; ++f) { 5440 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5441 const PetscInt *cone, *support; 5442 PetscInt size, s; 5443 5444 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5445 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5446 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5447 for (s = 0; s < size; ++s) { 5448 PetscInt r; 5449 5450 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5451 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5452 if (support[s] < cMax) { 5453 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5454 } else { 5455 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5456 } 5457 } 5458 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5459 #if 1 5460 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5461 for (p = 0; p < 4+size; ++p) { 5462 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); 5463 } 5464 #endif 5465 } 5466 /* Cell vertices have 6 supports */ 5467 for (c = cStart; c < cMax; ++c) { 5468 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5469 PetscInt supportNew[6]; 5470 5471 for (r = 0; r < 6; ++r) { 5472 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5473 } 5474 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5475 } 5476 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5477 break; 5478 default: 5479 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5480 } 5481 PetscFunctionReturn(0); 5482 } 5483 5484 #undef __FUNCT__ 5485 #define __FUNCT__ "CellRefinerSetCoordinates" 5486 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5487 { 5488 PetscSection coordSection, coordSectionNew; 5489 Vec coordinates, coordinatesNew; 5490 PetscScalar *coords, *coordsNew; 5491 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5492 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5493 PetscErrorCode ierr; 5494 5495 PetscFunctionBegin; 5496 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5497 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5498 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5499 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5500 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5501 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5502 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5503 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5504 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5505 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5506 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 5507 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5508 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5509 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 5510 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5511 if (cMax < 0) cMax = cEnd; 5512 if (fMax < 0) fMax = fEnd; 5513 if (eMax < 0) eMax = eEnd; 5514 /* All vertices have the spaceDim coordinates */ 5515 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5516 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 5517 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 5518 } 5519 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5520 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 5521 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5522 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5523 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 5524 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5525 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5526 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 5527 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 5528 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 5529 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5530 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5531 switch (refiner) { 5532 case REFINER_NOOP: break; 5533 case REFINER_HEX_3D: 5534 case REFINER_HYBRID_HEX_3D: 5535 /* Face vertices have the average of corner coordinates */ 5536 for (f = fStart; f < fMax; ++f) { 5537 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5538 PetscInt *cone = NULL; 5539 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5540 5541 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5542 for (p = 0; p < closureSize*2; p += 2) { 5543 const PetscInt point = cone[p]; 5544 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5545 } 5546 for (v = 0; v < coneSize; ++v) { 5547 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5548 } 5549 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5550 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5551 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5552 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5553 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5554 } 5555 case REFINER_HEX_2D: 5556 case REFINER_HYBRID_HEX_2D: 5557 case REFINER_SIMPLEX_1D: 5558 /* Cell vertices have the average of corner coordinates */ 5559 for (c = cStart; c < cMax; ++c) { 5560 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 5561 PetscInt *cone = NULL; 5562 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5563 5564 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5565 for (p = 0; p < closureSize*2; p += 2) { 5566 const PetscInt point = cone[p]; 5567 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5568 } 5569 for (v = 0; v < coneSize; ++v) { 5570 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5571 } 5572 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5573 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5574 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5575 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5576 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5577 } 5578 case REFINER_SIMPLEX_2D: 5579 case REFINER_HYBRID_SIMPLEX_2D: 5580 case REFINER_SIMPLEX_3D: 5581 case REFINER_HYBRID_SIMPLEX_3D: 5582 /* Edge vertices have the average of endpoint coordinates */ 5583 for (e = eStart; e < eMax; ++e) { 5584 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5585 const PetscInt *cone; 5586 PetscInt coneSize, offA, offB, offnew, d; 5587 5588 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5589 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5590 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5591 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5592 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5593 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5594 ierr = DMPlexLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 5595 for (d = 0; d < spaceDim; ++d) { 5596 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 5597 } 5598 } 5599 /* Old vertices have the same coordinates */ 5600 for (v = vStart; v < vEnd; ++v) { 5601 const PetscInt newv = vStartNew + (v - vStart); 5602 PetscInt off, offnew, d; 5603 5604 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5605 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5606 for (d = 0; d < spaceDim; ++d) { 5607 coordsNew[offnew+d] = coords[off+d]; 5608 } 5609 } 5610 break; 5611 default: 5612 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5613 } 5614 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5615 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5616 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5617 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5618 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5619 if (dm->maxCell) { 5620 const PetscReal *maxCell, *L; 5621 ierr = DMGetPeriodicity(dm, &maxCell, &L);CHKERRQ(ierr); 5622 ierr = DMSetPeriodicity(rdm, maxCell, L);CHKERRQ(ierr); 5623 } 5624 PetscFunctionReturn(0); 5625 } 5626 5627 #undef __FUNCT__ 5628 #define __FUNCT__ "DMPlexCreateProcessSF" 5629 /*@ 5630 DMPlexCreateProcessSF - Create an SF which just has process connectivity 5631 5632 Collective on DM 5633 5634 Input Parameters: 5635 + dm - The DM 5636 - sfPoint - The PetscSF which encodes point connectivity 5637 5638 Output Parameters: 5639 + processRanks - A list of process neighbors, or NULL 5640 - sfProcess - An SF encoding the process connectivity, or NULL 5641 5642 Level: developer 5643 5644 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 5645 @*/ 5646 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5647 { 5648 PetscInt numRoots, numLeaves, l; 5649 const PetscInt *localPoints; 5650 const PetscSFNode *remotePoints; 5651 PetscInt *localPointsNew; 5652 PetscSFNode *remotePointsNew; 5653 PetscInt *ranks, *ranksNew; 5654 PetscMPIInt numProcs; 5655 PetscErrorCode ierr; 5656 5657 PetscFunctionBegin; 5658 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5659 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 5660 if (processRanks) {PetscValidPointer(processRanks, 3);} 5661 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 5662 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &numProcs);CHKERRQ(ierr); 5663 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5664 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5665 for (l = 0; l < numLeaves; ++l) { 5666 ranks[l] = remotePoints[l].rank; 5667 } 5668 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5669 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5670 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5671 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5672 for (l = 0; l < numLeaves; ++l) { 5673 ranksNew[l] = ranks[l]; 5674 localPointsNew[l] = l; 5675 remotePointsNew[l].index = 0; 5676 remotePointsNew[l].rank = ranksNew[l]; 5677 } 5678 ierr = PetscFree(ranks);CHKERRQ(ierr); 5679 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 5680 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 5681 if (sfProcess) { 5682 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5683 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 5684 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5685 ierr = PetscSFSetGraph(*sfProcess, numProcs, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5686 } 5687 PetscFunctionReturn(0); 5688 } 5689 5690 #undef __FUNCT__ 5691 #define __FUNCT__ "CellRefinerCreateSF" 5692 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5693 { 5694 PetscSF sf, sfNew, sfProcess; 5695 IS processRanks; 5696 MPI_Datatype depthType; 5697 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5698 const PetscInt *localPoints, *neighbors; 5699 const PetscSFNode *remotePoints; 5700 PetscInt *localPointsNew; 5701 PetscSFNode *remotePointsNew; 5702 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5703 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5704 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5705 PetscErrorCode ierr; 5706 5707 PetscFunctionBegin; 5708 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5709 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5710 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5711 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5712 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5713 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5714 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5715 cMax = cMax < 0 ? cEnd : cMax; 5716 fMax = fMax < 0 ? fEnd : fMax; 5717 eMax = eMax < 0 ? eEnd : eMax; 5718 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5719 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5720 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5721 /* Calculate size of new SF */ 5722 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5723 if (numRoots < 0) PetscFunctionReturn(0); 5724 for (l = 0; l < numLeaves; ++l) { 5725 const PetscInt p = localPoints[l]; 5726 5727 switch (refiner) { 5728 case REFINER_SIMPLEX_1D: 5729 if ((p >= vStart) && (p < vEnd)) { 5730 /* Interior vertices stay the same */ 5731 ++numLeavesNew; 5732 } else if ((p >= cStart && p < cMax)) { 5733 /* Interior cells add new cells and interior vertices */ 5734 numLeavesNew += 2 + 1; 5735 } 5736 break; 5737 case REFINER_SIMPLEX_2D: 5738 case REFINER_HYBRID_SIMPLEX_2D: 5739 if ((p >= vStart) && (p < vEnd)) { 5740 /* Interior vertices stay the same */ 5741 ++numLeavesNew; 5742 } else if ((p >= fStart) && (p < fMax)) { 5743 /* Interior faces add new faces and vertex */ 5744 numLeavesNew += 2 + 1; 5745 } else if ((p >= fMax) && (p < fEnd)) { 5746 /* Hybrid faces stay the same */ 5747 ++numLeavesNew; 5748 } else if ((p >= cStart) && (p < cMax)) { 5749 /* Interior cells add new cells and interior faces */ 5750 numLeavesNew += 4 + 3; 5751 } else if ((p >= cMax) && (p < cEnd)) { 5752 /* Hybrid cells add new cells and hybrid face */ 5753 numLeavesNew += 2 + 1; 5754 } 5755 break; 5756 case REFINER_HEX_2D: 5757 case REFINER_HYBRID_HEX_2D: 5758 if ((p >= vStart) && (p < vEnd)) { 5759 /* Interior vertices stay the same */ 5760 ++numLeavesNew; 5761 } else if ((p >= fStart) && (p < fMax)) { 5762 /* Interior faces add new faces and vertex */ 5763 numLeavesNew += 2 + 1; 5764 } else if ((p >= fMax) && (p < fEnd)) { 5765 /* Hybrid faces stay the same */ 5766 ++numLeavesNew; 5767 } else if ((p >= cStart) && (p < cMax)) { 5768 /* Interior cells add new cells, interior faces, and vertex */ 5769 numLeavesNew += 4 + 4 + 1; 5770 } else if ((p >= cMax) && (p < cEnd)) { 5771 /* Hybrid cells add new cells and hybrid face */ 5772 numLeavesNew += 2 + 1; 5773 } 5774 break; 5775 case REFINER_SIMPLEX_3D: 5776 case REFINER_HYBRID_SIMPLEX_3D: 5777 if ((p >= vStart) && (p < vEnd)) { 5778 /* Interior vertices stay the same */ 5779 ++numLeavesNew; 5780 } else if ((p >= eStart) && (p < eMax)) { 5781 /* Interior edges add new edges and vertex */ 5782 numLeavesNew += 2 + 1; 5783 } else if ((p >= eMax) && (p < eEnd)) { 5784 /* Hybrid edges stay the same */ 5785 ++numLeavesNew; 5786 } else if ((p >= fStart) && (p < fMax)) { 5787 /* Interior faces add new faces and edges */ 5788 numLeavesNew += 4 + 3; 5789 } else if ((p >= fMax) && (p < fEnd)) { 5790 /* Hybrid faces add new faces and edges */ 5791 numLeavesNew += 2 + 1; 5792 } else if ((p >= cStart) && (p < cMax)) { 5793 /* Interior cells add new cells, faces, and edges */ 5794 numLeavesNew += 8 + 8 + 1; 5795 } else if ((p >= cMax) && (p < cEnd)) { 5796 /* Hybrid cells add new cells and faces */ 5797 numLeavesNew += 4 + 3; 5798 } 5799 break; 5800 case REFINER_HEX_3D: 5801 case REFINER_HYBRID_HEX_3D: 5802 if ((p >= vStart) && (p < vEnd)) { 5803 /* Old vertices stay the same */ 5804 ++numLeavesNew; 5805 } else if ((p >= eStart) && (p < eMax)) { 5806 /* Interior edges add new edges, and vertex */ 5807 numLeavesNew += 2 + 1; 5808 } else if ((p >= eMax) && (p < eEnd)) { 5809 /* Hybrid edges stay the same */ 5810 ++numLeavesNew; 5811 } else if ((p >= fStart) && (p < fMax)) { 5812 /* Interior faces add new faces, edges, and vertex */ 5813 numLeavesNew += 4 + 4 + 1; 5814 } else if ((p >= fMax) && (p < fEnd)) { 5815 /* Hybrid faces add new faces and edges */ 5816 numLeavesNew += 2 + 1; 5817 } else if ((p >= cStart) && (p < cMax)) { 5818 /* Interior cells add new cells, faces, edges, and vertex */ 5819 numLeavesNew += 8 + 12 + 6 + 1; 5820 } else if ((p >= cStart) && (p < cEnd)) { 5821 /* Hybrid cells add new cells, faces, and edges */ 5822 numLeavesNew += 4 + 4 + 1; 5823 } 5824 break; 5825 default: 5826 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5827 } 5828 } 5829 /* Communicate depthSizes for each remote rank */ 5830 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5831 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5832 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5833 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5834 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5835 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5836 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5837 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5838 for (n = 0; n < numNeighbors; ++n) { 5839 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5840 } 5841 depthSizeOld[depth] = cMax; 5842 depthSizeOld[0] = vMax; 5843 depthSizeOld[depth-1] = fMax; 5844 depthSizeOld[1] = eMax; 5845 5846 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5847 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5848 5849 depthSizeOld[depth] = cEnd - cStart; 5850 depthSizeOld[0] = vEnd - vStart; 5851 depthSizeOld[depth-1] = fEnd - fStart; 5852 depthSizeOld[1] = eEnd - eStart; 5853 5854 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5855 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5856 for (n = 0; n < numNeighbors; ++n) { 5857 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5858 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 5859 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]; 5860 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 5861 } 5862 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5863 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5864 /* Calculate new point SF */ 5865 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5866 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5867 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5868 for (l = 0, m = 0; l < numLeaves; ++l) { 5869 PetscInt p = localPoints[l]; 5870 PetscInt rp = remotePoints[l].index, n; 5871 PetscMPIInt rrank = remotePoints[l].rank; 5872 5873 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5874 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5875 switch (refiner) { 5876 case REFINER_SIMPLEX_1D: 5877 if ((p >= vStart) && (p < vEnd)) { 5878 /* Old vertices stay the same */ 5879 localPointsNew[m] = vStartNew + (p - vStart); 5880 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5881 remotePointsNew[m].rank = rrank; 5882 ++m; 5883 } else if ((p >= cStart) && (p < cMax)) { 5884 /* Old interior cells add new cells and vertex */ 5885 for (r = 0; r < 2; ++r, ++m) { 5886 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 5887 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 5888 remotePointsNew[m].rank = rrank; 5889 } 5890 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 5891 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 5892 remotePointsNew[m].rank = rrank; 5893 ++m; 5894 } 5895 break; 5896 case REFINER_SIMPLEX_2D: 5897 case REFINER_HYBRID_SIMPLEX_2D: 5898 if ((p >= vStart) && (p < vEnd)) { 5899 /* Old vertices stay the same */ 5900 localPointsNew[m] = vStartNew + (p - vStart); 5901 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5902 remotePointsNew[m].rank = rrank; 5903 ++m; 5904 } else if ((p >= fStart) && (p < fMax)) { 5905 /* Old interior faces add new faces and vertex */ 5906 for (r = 0; r < 2; ++r, ++m) { 5907 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5908 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5909 remotePointsNew[m].rank = rrank; 5910 } 5911 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5912 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5913 remotePointsNew[m].rank = rrank; 5914 ++m; 5915 } else if ((p >= fMax) && (p < fEnd)) { 5916 /* Old hybrid faces stay the same */ 5917 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5918 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5919 remotePointsNew[m].rank = rrank; 5920 ++m; 5921 } else if ((p >= cStart) && (p < cMax)) { 5922 /* Old interior cells add new cells and interior faces */ 5923 for (r = 0; r < 4; ++r, ++m) { 5924 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5925 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5926 remotePointsNew[m].rank = rrank; 5927 } 5928 for (r = 0; r < 3; ++r, ++m) { 5929 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5930 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5931 remotePointsNew[m].rank = rrank; 5932 } 5933 } else if ((p >= cMax) && (p < cEnd)) { 5934 /* Old hybrid cells add new cells and hybrid face */ 5935 for (r = 0; r < 2; ++r, ++m) { 5936 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5937 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5938 remotePointsNew[m].rank = rrank; 5939 } 5940 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5941 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]); 5942 remotePointsNew[m].rank = rrank; 5943 ++m; 5944 } 5945 break; 5946 case REFINER_HEX_2D: 5947 case REFINER_HYBRID_HEX_2D: 5948 if ((p >= vStart) && (p < vEnd)) { 5949 /* Old vertices stay the same */ 5950 localPointsNew[m] = vStartNew + (p - vStart); 5951 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5952 remotePointsNew[m].rank = rrank; 5953 ++m; 5954 } else if ((p >= fStart) && (p < fMax)) { 5955 /* Old interior faces add new faces and vertex */ 5956 for (r = 0; r < 2; ++r, ++m) { 5957 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5958 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5959 remotePointsNew[m].rank = rrank; 5960 } 5961 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5962 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5963 remotePointsNew[m].rank = rrank; 5964 ++m; 5965 } else if ((p >= fMax) && (p < fEnd)) { 5966 /* Old hybrid faces stay the same */ 5967 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5968 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5969 remotePointsNew[m].rank = rrank; 5970 ++m; 5971 } else if ((p >= cStart) && (p < cMax)) { 5972 /* Old interior cells add new cells, interior faces, and vertex */ 5973 for (r = 0; r < 4; ++r, ++m) { 5974 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5975 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5976 remotePointsNew[m].rank = rrank; 5977 } 5978 for (r = 0; r < 4; ++r, ++m) { 5979 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5980 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5981 remotePointsNew[m].rank = rrank; 5982 } 5983 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 5984 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 5985 remotePointsNew[m].rank = rrank; 5986 ++m; 5987 } else if ((p >= cStart) && (p < cMax)) { 5988 /* Old hybrid cells add new cells and hybrid face */ 5989 for (r = 0; r < 2; ++r, ++m) { 5990 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5991 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5992 remotePointsNew[m].rank = rrank; 5993 } 5994 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5995 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]); 5996 remotePointsNew[m].rank = rrank; 5997 ++m; 5998 } 5999 break; 6000 case REFINER_SIMPLEX_3D: 6001 case REFINER_HYBRID_SIMPLEX_3D: 6002 if ((p >= vStart) && (p < vEnd)) { 6003 /* Interior vertices stay the same */ 6004 localPointsNew[m] = vStartNew + (p - vStart); 6005 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6006 remotePointsNew[m].rank = rrank; 6007 ++m; 6008 } else if ((p >= eStart) && (p < eMax)) { 6009 /* Interior edges add new edges and vertex */ 6010 for (r = 0; r < 2; ++r, ++m) { 6011 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6012 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6013 remotePointsNew[m].rank = rrank; 6014 } 6015 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6016 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6017 remotePointsNew[m].rank = rrank; 6018 ++m; 6019 } else if ((p >= eMax) && (p < eEnd)) { 6020 /* Hybrid edges stay the same */ 6021 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6022 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]); 6023 remotePointsNew[m].rank = rrank; 6024 ++m; 6025 } else if ((p >= fStart) && (p < fMax)) { 6026 /* Interior faces add new faces and edges */ 6027 for (r = 0; r < 4; ++r, ++m) { 6028 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6029 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6030 remotePointsNew[m].rank = rrank; 6031 } 6032 for (r = 0; r < 3; ++r, ++m) { 6033 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6034 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 6035 remotePointsNew[m].rank = rrank; 6036 } 6037 } else if ((p >= fMax) && (p < fEnd)) { 6038 /* Hybrid faces add new faces and edges */ 6039 for (r = 0; r < 2; ++r, ++m) { 6040 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6041 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; 6042 remotePointsNew[m].rank = rrank; 6043 } 6044 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 6045 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]); 6046 remotePointsNew[m].rank = rrank; 6047 ++m; 6048 } else if ((p >= cStart) && (p < cMax)) { 6049 /* Interior cells add new cells, faces, and edges */ 6050 for (r = 0; r < 8; ++r, ++m) { 6051 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6052 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6053 remotePointsNew[m].rank = rrank; 6054 } 6055 for (r = 0; r < 8; ++r, ++m) { 6056 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6057 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 6058 remotePointsNew[m].rank = rrank; 6059 } 6060 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 6061 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; 6062 remotePointsNew[m].rank = rrank; 6063 ++m; 6064 } else if ((p >= cMax) && (p < cEnd)) { 6065 /* Hybrid cells add new cells and faces */ 6066 for (r = 0; r < 4; ++r, ++m) { 6067 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6068 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6069 remotePointsNew[m].rank = rrank; 6070 } 6071 for (r = 0; r < 3; ++r, ++m) { 6072 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6073 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; 6074 remotePointsNew[m].rank = rrank; 6075 } 6076 } 6077 break; 6078 case REFINER_HEX_3D: 6079 case REFINER_HYBRID_HEX_3D: 6080 if ((p >= vStart) && (p < vEnd)) { 6081 /* Interior vertices stay the same */ 6082 localPointsNew[m] = vStartNew + (p - vStart); 6083 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6084 remotePointsNew[m].rank = rrank; 6085 ++m; 6086 } else if ((p >= eStart) && (p < eMax)) { 6087 /* Interior edges add new edges and vertex */ 6088 for (r = 0; r < 2; ++r, ++m) { 6089 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6090 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6091 remotePointsNew[m].rank = rrank; 6092 } 6093 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6094 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6095 remotePointsNew[m].rank = rrank; 6096 ++m; 6097 } else if ((p >= eMax) && (p < eEnd)) { 6098 /* Hybrid edges stay the same */ 6099 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6100 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]); 6101 remotePointsNew[m].rank = rrank; 6102 ++m; 6103 } else if ((p >= fStart) && (p < fMax)) { 6104 /* Interior faces add new faces, edges, and vertex */ 6105 for (r = 0; r < 4; ++r, ++m) { 6106 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6107 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6108 remotePointsNew[m].rank = rrank; 6109 } 6110 for (r = 0; r < 4; ++r, ++m) { 6111 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6112 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 6113 remotePointsNew[m].rank = rrank; 6114 } 6115 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6116 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 6117 remotePointsNew[m].rank = rrank; 6118 ++m; 6119 } else if ((p >= fMax) && (p < fEnd)) { 6120 /* Hybrid faces add new faces and edges */ 6121 for (r = 0; r < 2; ++r, ++m) { 6122 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6123 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; 6124 remotePointsNew[m].rank = rrank; 6125 } 6126 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 6127 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]); 6128 remotePointsNew[m].rank = rrank; 6129 ++m; 6130 } else if ((p >= cStart) && (p < cMax)) { 6131 /* Interior cells add new cells, faces, edges, and vertex */ 6132 for (r = 0; r < 8; ++r, ++m) { 6133 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6134 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6135 remotePointsNew[m].rank = rrank; 6136 } 6137 for (r = 0; r < 12; ++r, ++m) { 6138 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6139 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6140 remotePointsNew[m].rank = rrank; 6141 } 6142 for (r = 0; r < 6; ++r, ++m) { 6143 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6144 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; 6145 remotePointsNew[m].rank = rrank; 6146 } 6147 for (r = 0; r < 1; ++r, ++m) { 6148 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6149 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6150 remotePointsNew[m].rank = rrank; 6151 } 6152 } else if ((p >= cMax) && (p < cEnd)) { 6153 /* Hybrid cells add new cells, faces, and edges */ 6154 for (r = 0; r < 4; ++r, ++m) { 6155 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6156 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6157 remotePointsNew[m].rank = rrank; 6158 } 6159 for (r = 0; r < 4; ++r, ++m) { 6160 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6161 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; 6162 remotePointsNew[m].rank = rrank; 6163 } 6164 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 6165 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]); 6166 remotePointsNew[m].rank = rrank; 6167 ++m; 6168 } 6169 break; 6170 default: 6171 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6172 } 6173 } 6174 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6175 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6176 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6177 { 6178 PetscSFNode *rp, *rtmp; 6179 PetscInt *lp, *idx, *ltmp, i; 6180 6181 /* SF needs sorted leaves to correct calculate Gather */ 6182 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 6183 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 6184 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 6185 for (i = 0; i < numLeavesNew; ++i) { 6186 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); 6187 idx[i] = i; 6188 } 6189 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 6190 for (i = 0; i < numLeavesNew; ++i) { 6191 lp[i] = localPointsNew[idx[i]]; 6192 rp[i] = remotePointsNew[idx[i]]; 6193 } 6194 ltmp = localPointsNew; 6195 localPointsNew = lp; 6196 rtmp = remotePointsNew; 6197 remotePointsNew = rp; 6198 ierr = PetscFree(idx);CHKERRQ(ierr); 6199 ierr = PetscFree(ltmp);CHKERRQ(ierr); 6200 ierr = PetscFree(rtmp);CHKERRQ(ierr); 6201 } 6202 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6203 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6204 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6205 PetscFunctionReturn(0); 6206 } 6207 6208 #undef __FUNCT__ 6209 #define __FUNCT__ "CellRefinerCreateLabels" 6210 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6211 { 6212 PetscInt numLabels, l; 6213 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6214 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6215 PetscErrorCode ierr; 6216 6217 PetscFunctionBegin; 6218 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6219 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6220 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6221 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6222 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6223 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6224 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6225 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6226 switch (refiner) { 6227 case REFINER_NOOP: 6228 case REFINER_SIMPLEX_1D: 6229 case REFINER_SIMPLEX_2D: 6230 case REFINER_HEX_2D: 6231 case REFINER_SIMPLEX_3D: 6232 case REFINER_HEX_3D: 6233 break; 6234 case REFINER_HYBRID_SIMPLEX_3D: 6235 case REFINER_HYBRID_HEX_3D: 6236 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6237 case REFINER_HYBRID_SIMPLEX_2D: 6238 case REFINER_HYBRID_HEX_2D: 6239 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6240 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6241 break; 6242 default: 6243 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6244 } 6245 for (l = 0; l < numLabels; ++l) { 6246 DMLabel label, labelNew; 6247 const char *lname; 6248 PetscBool isDepth; 6249 IS valueIS; 6250 const PetscInt *values; 6251 PetscInt numValues, val; 6252 6253 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6254 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6255 if (isDepth) continue; 6256 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6257 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6258 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6259 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6260 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6261 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6262 for (val = 0; val < numValues; ++val) { 6263 IS pointIS; 6264 const PetscInt *points; 6265 PetscInt numPoints, n; 6266 6267 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6268 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6269 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6270 /* Ensure refined label is created with same number of strata as 6271 * original (even if no entries here). */ 6272 if (!numPoints) { 6273 ierr = DMLabelSetValue(labelNew, 0, values[val]);CHKERRQ(ierr); 6274 ierr = DMLabelClearValue(labelNew, 0, values[val]);CHKERRQ(ierr); 6275 } 6276 for (n = 0; n < numPoints; ++n) { 6277 const PetscInt p = points[n]; 6278 switch (refiner) { 6279 case REFINER_SIMPLEX_1D: 6280 if ((p >= vStart) && (p < vEnd)) { 6281 /* Old vertices stay the same */ 6282 newp = vStartNew + (p - vStart); 6283 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6284 } else if ((p >= cStart) && (p < cEnd)) { 6285 /* Old cells add new cells and vertex */ 6286 newp = vStartNew + (vEnd - vStart) + (p - cStart); 6287 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6288 for (r = 0; r < 2; ++r) { 6289 newp = cStartNew + (p - cStart)*2 + r; 6290 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6291 } 6292 } 6293 break; 6294 case REFINER_SIMPLEX_2D: 6295 if ((p >= vStart) && (p < vEnd)) { 6296 /* Old vertices stay the same */ 6297 newp = vStartNew + (p - vStart); 6298 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6299 } else if ((p >= fStart) && (p < fEnd)) { 6300 /* Old faces add new faces and vertex */ 6301 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6302 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6303 for (r = 0; r < 2; ++r) { 6304 newp = fStartNew + (p - fStart)*2 + r; 6305 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6306 } 6307 } else if ((p >= cStart) && (p < cEnd)) { 6308 /* Old cells add new cells and interior faces */ 6309 for (r = 0; r < 4; ++r) { 6310 newp = cStartNew + (p - cStart)*4 + r; 6311 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6312 } 6313 for (r = 0; r < 3; ++r) { 6314 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6315 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6316 } 6317 } 6318 break; 6319 case REFINER_HEX_2D: 6320 if ((p >= vStart) && (p < vEnd)) { 6321 /* Old vertices stay the same */ 6322 newp = vStartNew + (p - vStart); 6323 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6324 } else if ((p >= fStart) && (p < fEnd)) { 6325 /* Old faces add new faces and vertex */ 6326 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6327 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6328 for (r = 0; r < 2; ++r) { 6329 newp = fStartNew + (p - fStart)*2 + r; 6330 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6331 } 6332 } else if ((p >= cStart) && (p < cEnd)) { 6333 /* Old cells add new cells and interior faces and vertex */ 6334 for (r = 0; r < 4; ++r) { 6335 newp = cStartNew + (p - cStart)*4 + r; 6336 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6337 } 6338 for (r = 0; r < 4; ++r) { 6339 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6340 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6341 } 6342 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6343 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6344 } 6345 break; 6346 case REFINER_HYBRID_SIMPLEX_2D: 6347 if ((p >= vStart) && (p < vEnd)) { 6348 /* Old vertices stay the same */ 6349 newp = vStartNew + (p - vStart); 6350 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6351 } else if ((p >= fStart) && (p < fMax)) { 6352 /* Old interior faces add new faces and vertex */ 6353 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6354 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6355 for (r = 0; r < 2; ++r) { 6356 newp = fStartNew + (p - fStart)*2 + r; 6357 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6358 } 6359 } else if ((p >= fMax) && (p < fEnd)) { 6360 /* Old hybrid faces stay the same */ 6361 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6362 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6363 } else if ((p >= cStart) && (p < cMax)) { 6364 /* Old interior cells add new cells and interior faces */ 6365 for (r = 0; r < 4; ++r) { 6366 newp = cStartNew + (p - cStart)*4 + r; 6367 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6368 } 6369 for (r = 0; r < 3; ++r) { 6370 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6371 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6372 } 6373 } else if ((p >= cMax) && (p < cEnd)) { 6374 /* Old hybrid cells add new cells and hybrid face */ 6375 for (r = 0; r < 2; ++r) { 6376 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6377 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6378 } 6379 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6380 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6381 } 6382 break; 6383 case REFINER_HYBRID_HEX_2D: 6384 if ((p >= vStart) && (p < vEnd)) { 6385 /* Old vertices stay the same */ 6386 newp = vStartNew + (p - vStart); 6387 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6388 } else if ((p >= fStart) && (p < fMax)) { 6389 /* Old interior faces add new faces and vertex */ 6390 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6391 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6392 for (r = 0; r < 2; ++r) { 6393 newp = fStartNew + (p - fStart)*2 + r; 6394 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6395 } 6396 } else if ((p >= fMax) && (p < fEnd)) { 6397 /* Old hybrid faces stay the same */ 6398 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6399 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6400 } else if ((p >= cStart) && (p < cMax)) { 6401 /* Old interior cells add new cells, interior faces, and vertex */ 6402 for (r = 0; r < 4; ++r) { 6403 newp = cStartNew + (p - cStart)*4 + r; 6404 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6405 } 6406 for (r = 0; r < 4; ++r) { 6407 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6408 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6409 } 6410 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6411 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6412 } else if ((p >= cMax) && (p < cEnd)) { 6413 /* Old hybrid cells add new cells and hybrid face */ 6414 for (r = 0; r < 2; ++r) { 6415 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6416 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6417 } 6418 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6419 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6420 } 6421 break; 6422 case REFINER_SIMPLEX_3D: 6423 if ((p >= vStart) && (p < vEnd)) { 6424 /* Old vertices stay the same */ 6425 newp = vStartNew + (p - vStart); 6426 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6427 } else if ((p >= eStart) && (p < eEnd)) { 6428 /* Old edges add new edges and vertex */ 6429 for (r = 0; r < 2; ++r) { 6430 newp = eStartNew + (p - eStart)*2 + r; 6431 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6432 } 6433 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6434 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6435 } else if ((p >= fStart) && (p < fEnd)) { 6436 /* Old faces add new faces and edges */ 6437 for (r = 0; r < 4; ++r) { 6438 newp = fStartNew + (p - fStart)*4 + r; 6439 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6440 } 6441 for (r = 0; r < 3; ++r) { 6442 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6443 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6444 } 6445 } else if ((p >= cStart) && (p < cEnd)) { 6446 /* Old cells add new cells and interior faces and edges */ 6447 for (r = 0; r < 8; ++r) { 6448 newp = cStartNew + (p - cStart)*8 + r; 6449 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6450 } 6451 for (r = 0; r < 8; ++r) { 6452 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6453 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6454 } 6455 for (r = 0; r < 1; ++r) { 6456 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6457 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6458 } 6459 } 6460 break; 6461 case REFINER_HYBRID_SIMPLEX_3D: 6462 if ((p >= vStart) && (p < vEnd)) { 6463 /* Interior vertices stay the same */ 6464 newp = vStartNew + (p - vStart); 6465 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6466 } else if ((p >= eStart) && (p < eMax)) { 6467 /* Interior edges add new edges and vertex */ 6468 for (r = 0; r < 2; ++r) { 6469 newp = eStartNew + (p - eStart)*2 + r; 6470 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6471 } 6472 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6473 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6474 } else if ((p >= eMax) && (p < eEnd)) { 6475 /* Hybrid edges stay the same */ 6476 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6477 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6478 } else if ((p >= fStart) && (p < fMax)) { 6479 /* Interior faces add new faces and edges */ 6480 for (r = 0; r < 4; ++r) { 6481 newp = fStartNew + (p - fStart)*4 + r; 6482 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6483 } 6484 for (r = 0; r < 3; ++r) { 6485 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6486 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6487 } 6488 } else if ((p >= fMax) && (p < fEnd)) { 6489 /* Hybrid faces add new faces and edges */ 6490 for (r = 0; r < 2; ++r) { 6491 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6492 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6493 } 6494 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6495 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6496 } else if ((p >= cStart) && (p < cMax)) { 6497 /* Interior cells add new cells, faces, and edges */ 6498 for (r = 0; r < 8; ++r) { 6499 newp = cStartNew + (p - cStart)*8 + r; 6500 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6501 } 6502 for (r = 0; r < 8; ++r) { 6503 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6504 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6505 } 6506 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6507 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6508 } else if ((p >= cMax) && (p < cEnd)) { 6509 /* Hybrid cells add new cells and faces */ 6510 for (r = 0; r < 4; ++r) { 6511 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6512 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6513 } 6514 for (r = 0; r < 3; ++r) { 6515 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6516 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6517 } 6518 } 6519 break; 6520 case REFINER_HEX_3D: 6521 if ((p >= vStart) && (p < vEnd)) { 6522 /* Old vertices stay the same */ 6523 newp = vStartNew + (p - vStart); 6524 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6525 } else if ((p >= eStart) && (p < eEnd)) { 6526 /* Old edges add new edges and vertex */ 6527 for (r = 0; r < 2; ++r) { 6528 newp = eStartNew + (p - eStart)*2 + r; 6529 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6530 } 6531 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6532 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6533 } else if ((p >= fStart) && (p < fEnd)) { 6534 /* Old faces add new faces, edges, and vertex */ 6535 for (r = 0; r < 4; ++r) { 6536 newp = fStartNew + (p - fStart)*4 + r; 6537 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6538 } 6539 for (r = 0; r < 4; ++r) { 6540 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6541 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6542 } 6543 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6544 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6545 } else if ((p >= cStart) && (p < cEnd)) { 6546 /* Old cells add new cells, faces, edges, and vertex */ 6547 for (r = 0; r < 8; ++r) { 6548 newp = cStartNew + (p - cStart)*8 + r; 6549 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6550 } 6551 for (r = 0; r < 12; ++r) { 6552 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6553 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6554 } 6555 for (r = 0; r < 6; ++r) { 6556 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6557 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6558 } 6559 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6560 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6561 } 6562 break; 6563 case REFINER_HYBRID_HEX_3D: 6564 if ((p >= vStart) && (p < vEnd)) { 6565 /* Interior vertices stay the same */ 6566 newp = vStartNew + (p - vStart); 6567 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6568 } else if ((p >= eStart) && (p < eMax)) { 6569 /* Interior edges add new edges and vertex */ 6570 for (r = 0; r < 2; ++r) { 6571 newp = eStartNew + (p - eStart)*2 + r; 6572 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6573 } 6574 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6575 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6576 } else if ((p >= eMax) && (p < eEnd)) { 6577 /* Hybrid edges stay the same */ 6578 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6579 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6580 } else if ((p >= fStart) && (p < fMax)) { 6581 /* Interior faces add new faces, edges, and vertex */ 6582 for (r = 0; r < 4; ++r) { 6583 newp = fStartNew + (p - fStart)*4 + r; 6584 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6585 } 6586 for (r = 0; r < 4; ++r) { 6587 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6588 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6589 } 6590 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6591 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6592 } else if ((p >= fMax) && (p < fEnd)) { 6593 /* Hybrid faces add new faces and edges */ 6594 for (r = 0; r < 2; ++r) { 6595 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6596 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6597 } 6598 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6599 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6600 } else if ((p >= cStart) && (p < cMax)) { 6601 /* Interior cells add new cells, faces, edges, and vertex */ 6602 for (r = 0; r < 8; ++r) { 6603 newp = cStartNew + (p - cStart)*8 + r; 6604 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6605 } 6606 for (r = 0; r < 12; ++r) { 6607 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6608 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6609 } 6610 for (r = 0; r < 6; ++r) { 6611 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6612 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6613 } 6614 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6615 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6616 } else if ((p >= cMax) && (p < cEnd)) { 6617 /* Hybrid cells add new cells, faces, and edges */ 6618 for (r = 0; r < 4; ++r) { 6619 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6620 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6621 } 6622 for (r = 0; r < 4; ++r) { 6623 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6624 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6625 } 6626 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6627 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6628 } 6629 break; 6630 default: 6631 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6632 } 6633 } 6634 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6635 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6636 } 6637 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6638 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6639 if (0) { 6640 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6641 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6642 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6643 } 6644 } 6645 PetscFunctionReturn(0); 6646 } 6647 6648 #undef __FUNCT__ 6649 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6650 /* This will only work for interpolated meshes */ 6651 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6652 { 6653 DM rdm; 6654 PetscInt *depthSize; 6655 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6656 PetscErrorCode ierr; 6657 6658 PetscFunctionBegin; 6659 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6660 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6661 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6662 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 6663 /* Calculate number of new points of each depth */ 6664 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6665 if (dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 6666 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 6667 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6668 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6669 /* Step 1: Set chart */ 6670 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6671 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6672 /* Step 2: Set cone/support sizes */ 6673 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6674 /* Step 3: Setup refined DM */ 6675 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6676 /* Step 4: Set cones and supports */ 6677 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6678 /* Step 5: Stratify */ 6679 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6680 /* Step 6: Create pointSF */ 6681 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6682 /* Step 7: Set coordinates for vertices */ 6683 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6684 /* Step 8: Create labels */ 6685 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6686 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6687 6688 *dmRefined = rdm; 6689 PetscFunctionReturn(0); 6690 } 6691 6692 #undef __FUNCT__ 6693 #define __FUNCT__ "DMPlexCreateCoarsePointIS" 6694 /*@ 6695 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 6696 6697 Input Parameter: 6698 . dm - The coarse DM 6699 6700 Output Parameter: 6701 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 6702 6703 Level: developer 6704 6705 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 6706 @*/ 6707 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 6708 { 6709 CellRefiner cellRefiner; 6710 PetscInt *depthSize, *fpoints; 6711 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6712 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 6713 PetscErrorCode ierr; 6714 6715 PetscFunctionBegin; 6716 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6717 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6718 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6719 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 6720 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 6721 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6722 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6723 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 6724 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 6725 switch (cellRefiner) { 6726 case REFINER_SIMPLEX_1D: 6727 case REFINER_SIMPLEX_2D: 6728 case REFINER_HYBRID_SIMPLEX_2D: 6729 case REFINER_HEX_2D: 6730 case REFINER_HYBRID_HEX_2D: 6731 case REFINER_SIMPLEX_3D: 6732 case REFINER_HYBRID_SIMPLEX_3D: 6733 case REFINER_HEX_3D: 6734 case REFINER_HYBRID_HEX_3D: 6735 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 6736 break; 6737 default: 6738 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 6739 } 6740 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 6741 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6742 PetscFunctionReturn(0); 6743 } 6744 6745 #undef __FUNCT__ 6746 #define __FUNCT__ "DMPlexSetRefinementUniform" 6747 /*@ 6748 DMPlexSetRefinementUniform - Set the flag for uniform refinement 6749 6750 Input Parameters: 6751 + dm - The DM 6752 - refinementUniform - The flag for uniform refinement 6753 6754 Level: developer 6755 6756 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6757 @*/ 6758 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6759 { 6760 DM_Plex *mesh = (DM_Plex*) dm->data; 6761 6762 PetscFunctionBegin; 6763 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6764 mesh->refinementUniform = refinementUniform; 6765 PetscFunctionReturn(0); 6766 } 6767 6768 #undef __FUNCT__ 6769 #define __FUNCT__ "DMPlexGetRefinementUniform" 6770 /*@ 6771 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 6772 6773 Input Parameter: 6774 . dm - The DM 6775 6776 Output Parameter: 6777 . refinementUniform - The flag for uniform refinement 6778 6779 Level: developer 6780 6781 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6782 @*/ 6783 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6784 { 6785 DM_Plex *mesh = (DM_Plex*) dm->data; 6786 6787 PetscFunctionBegin; 6788 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6789 PetscValidPointer(refinementUniform, 2); 6790 *refinementUniform = mesh->refinementUniform; 6791 PetscFunctionReturn(0); 6792 } 6793 6794 #undef __FUNCT__ 6795 #define __FUNCT__ "DMPlexSetRefinementLimit" 6796 /*@ 6797 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 6798 6799 Input Parameters: 6800 + dm - The DM 6801 - refinementLimit - The maximum cell volume in the refined mesh 6802 6803 Level: developer 6804 6805 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6806 @*/ 6807 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6808 { 6809 DM_Plex *mesh = (DM_Plex*) dm->data; 6810 6811 PetscFunctionBegin; 6812 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6813 mesh->refinementLimit = refinementLimit; 6814 PetscFunctionReturn(0); 6815 } 6816 6817 #undef __FUNCT__ 6818 #define __FUNCT__ "DMPlexGetRefinementLimit" 6819 /*@ 6820 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 6821 6822 Input Parameter: 6823 . dm - The DM 6824 6825 Output Parameter: 6826 . refinementLimit - The maximum cell volume in the refined mesh 6827 6828 Level: developer 6829 6830 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6831 @*/ 6832 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6833 { 6834 DM_Plex *mesh = (DM_Plex*) dm->data; 6835 6836 PetscFunctionBegin; 6837 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6838 PetscValidPointer(refinementLimit, 2); 6839 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6840 *refinementLimit = mesh->refinementLimit; 6841 PetscFunctionReturn(0); 6842 } 6843 6844 #undef __FUNCT__ 6845 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6846 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6847 { 6848 PetscInt dim, cStart, cEnd, coneSize, cMax; 6849 PetscErrorCode ierr; 6850 6851 PetscFunctionBegin; 6852 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6853 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6854 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 6855 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6856 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6857 switch (dim) { 6858 case 1: 6859 switch (coneSize) { 6860 case 2: 6861 *cellRefiner = REFINER_SIMPLEX_1D; 6862 break; 6863 default: 6864 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6865 } 6866 break; 6867 case 2: 6868 switch (coneSize) { 6869 case 3: 6870 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 6871 else *cellRefiner = REFINER_SIMPLEX_2D; 6872 break; 6873 case 4: 6874 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 6875 else *cellRefiner = REFINER_HEX_2D; 6876 break; 6877 default: 6878 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6879 } 6880 break; 6881 case 3: 6882 switch (coneSize) { 6883 case 4: 6884 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 6885 else *cellRefiner = REFINER_SIMPLEX_3D; 6886 break; 6887 case 6: 6888 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 6889 else *cellRefiner = REFINER_HEX_3D; 6890 break; 6891 default: 6892 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6893 } 6894 break; 6895 default: 6896 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6897 } 6898 PetscFunctionReturn(0); 6899 } 6900