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: {c, d, a, 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 #if 0 2413 /* B' tetrahedron: {a, e, b, f} */ 2414 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2415 orntNew[0] = -3; 2416 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2417 orntNew[1] = 1; 2418 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2419 orntNew[2] = 0; 2420 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2421 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2422 #else 2423 /* B' tetrahedron: {e, b, a, f} */ 2424 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2425 orntNew[0] = -2; 2426 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 2427 orntNew[1] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 1)+1) : GetTetSomething_Static(ornt[3], 1); 2428 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2429 orntNew[2] = 0; 2430 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2431 orntNew[3] = 0; 2432 #endif 2433 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2434 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2435 #if 1 2436 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); 2437 for (p = 0; p < 4; ++p) { 2438 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); 2439 } 2440 #endif 2441 #if 0 2442 /* C' tetrahedron: {c, b, f, a} */ 2443 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2444 orntNew[0] = -3; 2445 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2446 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2447 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2448 orntNew[2] = -3; 2449 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2450 orntNew[3] = -2; 2451 #else 2452 /* C' tetrahedron: {f, a, c, b} */ 2453 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2454 orntNew[0] = -2; 2455 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2456 orntNew[1] = -2; 2457 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2458 orntNew[2] = -1; 2459 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 2460 orntNew[3] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2461 #endif 2462 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2463 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2464 #if 1 2465 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); 2466 for (p = 0; p < 4; ++p) { 2467 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); 2468 } 2469 #endif 2470 #if 0 2471 /* D' tetrahedron: {d, f, e, a} */ 2472 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2473 orntNew[0] = -3; 2474 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2475 orntNew[1] = -3; 2476 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2477 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2478 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2479 orntNew[3] = -3; 2480 #else 2481 /* D' tetrahedron: {f, a, e, d} */ 2482 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2483 orntNew[0] = -2; 2484 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2485 orntNew[1] = -1; 2486 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2487 orntNew[2] = -2; 2488 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 2489 orntNew[3] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 1)+1) : GetTetSomething_Static(ornt[1], 1); 2490 #endif 2491 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2492 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2493 #if 1 2494 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); 2495 for (p = 0; p < 4; ++p) { 2496 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); 2497 } 2498 #endif 2499 } 2500 /* Split faces have 3 edges and the same cells as the parent */ 2501 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2502 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2503 for (f = fStart; f < fEnd; ++f) { 2504 const PetscInt newp = fStartNew + (f - fStart)*4; 2505 const PetscInt *cone, *ornt, *support; 2506 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2507 2508 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2509 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2510 /* A triangle */ 2511 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2512 orntNew[0] = ornt[0]; 2513 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2514 orntNew[1] = -2; 2515 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2516 orntNew[2] = ornt[2]; 2517 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2518 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2519 #if 1 2520 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); 2521 for (p = 0; p < 3; ++p) { 2522 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); 2523 } 2524 #endif 2525 /* B triangle */ 2526 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2527 orntNew[0] = ornt[0]; 2528 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2529 orntNew[1] = ornt[1]; 2530 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2531 orntNew[2] = -2; 2532 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2533 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2534 #if 1 2535 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); 2536 for (p = 0; p < 3; ++p) { 2537 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); 2538 } 2539 #endif 2540 /* C triangle */ 2541 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2542 orntNew[0] = -2; 2543 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2544 orntNew[1] = ornt[1]; 2545 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2546 orntNew[2] = ornt[2]; 2547 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2548 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2549 #if 1 2550 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); 2551 for (p = 0; p < 3; ++p) { 2552 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); 2553 } 2554 #endif 2555 /* D triangle */ 2556 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2557 orntNew[0] = 0; 2558 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2559 orntNew[1] = 0; 2560 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2561 orntNew[2] = 0; 2562 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2563 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2564 #if 1 2565 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); 2566 for (p = 0; p < 3; ++p) { 2567 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); 2568 } 2569 #endif 2570 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2571 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2572 for (r = 0; r < 4; ++r) { 2573 for (s = 0; s < supportSize; ++s) { 2574 PetscInt subf; 2575 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2576 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2577 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2578 for (c = 0; c < coneSize; ++c) { 2579 if (cone[c] == f) break; 2580 } 2581 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2582 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2583 } 2584 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2585 #if 1 2586 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); 2587 for (p = 0; p < supportSize; ++p) { 2588 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); 2589 } 2590 #endif 2591 } 2592 } 2593 /* Interior faces have 3 edges and 2 cells */ 2594 for (c = cStart; c < cEnd; ++c) { 2595 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2596 const PetscInt *cone, *ornt; 2597 PetscInt coneNew[3], orntNew[3]; 2598 PetscInt supportNew[2]; 2599 2600 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2601 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2602 /* Face A: {c, a, d} */ 2603 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2604 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2605 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2606 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2607 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2608 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2609 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2610 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2611 #if 1 2612 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2613 for (p = 0; p < 3; ++p) { 2614 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); 2615 } 2616 #endif 2617 supportNew[0] = (c - cStart)*8 + 0; 2618 supportNew[1] = (c - cStart)*8 + 0+4; 2619 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2620 #if 1 2621 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2622 for (p = 0; p < 2; ++p) { 2623 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); 2624 } 2625 #endif 2626 ++newp; 2627 /* Face B: {a, b, e} */ 2628 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2629 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2630 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2631 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2632 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2633 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2634 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2635 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2636 #if 1 2637 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2638 for (p = 0; p < 3; ++p) { 2639 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); 2640 } 2641 #endif 2642 supportNew[0] = (c - cStart)*8 + 1; 2643 supportNew[1] = (c - cStart)*8 + 1+4; 2644 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2645 #if 1 2646 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2647 for (p = 0; p < 2; ++p) { 2648 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); 2649 } 2650 #endif 2651 ++newp; 2652 /* Face C: {c, f, b} */ 2653 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2654 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2655 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2656 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2657 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2658 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2659 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2660 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2661 #if 1 2662 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2663 for (p = 0; p < 3; ++p) { 2664 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); 2665 } 2666 #endif 2667 supportNew[0] = (c - cStart)*8 + 2; 2668 supportNew[1] = (c - cStart)*8 + 2+4; 2669 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2670 #if 1 2671 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2672 for (p = 0; p < 2; ++p) { 2673 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); 2674 } 2675 #endif 2676 ++newp; 2677 /* Face D: {d, e, f} */ 2678 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2679 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2680 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2681 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2682 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2683 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2684 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2685 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2686 #if 1 2687 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2688 for (p = 0; p < 3; ++p) { 2689 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); 2690 } 2691 #endif 2692 supportNew[0] = (c - cStart)*8 + 3; 2693 supportNew[1] = (c - cStart)*8 + 3+4; 2694 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2695 #if 1 2696 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2697 for (p = 0; p < 2; ++p) { 2698 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); 2699 } 2700 #endif 2701 ++newp; 2702 /* Face E: {d, f, a} */ 2703 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2704 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2705 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2706 orntNew[1] = -2; 2707 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2708 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2709 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2710 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2711 #if 1 2712 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2713 for (p = 0; p < 3; ++p) { 2714 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); 2715 } 2716 #endif 2717 supportNew[0] = (c - cStart)*8 + 0+4; 2718 supportNew[1] = (c - cStart)*8 + 3+4; 2719 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2720 #if 1 2721 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2722 for (p = 0; p < 2; ++p) { 2723 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); 2724 } 2725 #endif 2726 ++newp; 2727 /* Face F: {c, a, f} */ 2728 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2729 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2730 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2731 orntNew[1] = 0; 2732 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2733 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2734 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2735 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2736 #if 1 2737 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2738 for (p = 0; p < 3; ++p) { 2739 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); 2740 } 2741 #endif 2742 supportNew[0] = (c - cStart)*8 + 0+4; 2743 supportNew[1] = (c - cStart)*8 + 2+4; 2744 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2745 #if 1 2746 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2747 for (p = 0; p < 2; ++p) { 2748 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); 2749 } 2750 #endif 2751 ++newp; 2752 /* Face G: {e, a, f} */ 2753 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2754 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2755 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2756 orntNew[1] = 0; 2757 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2758 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2759 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2760 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2761 #if 1 2762 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2763 for (p = 0; p < 3; ++p) { 2764 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); 2765 } 2766 #endif 2767 supportNew[0] = (c - cStart)*8 + 1+4; 2768 supportNew[1] = (c - cStart)*8 + 3+4; 2769 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2770 #if 1 2771 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2772 for (p = 0; p < 2; ++p) { 2773 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); 2774 } 2775 #endif 2776 ++newp; 2777 /* Face H: {a, b, f} */ 2778 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2779 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2780 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2781 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2782 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2783 orntNew[2] = -2; 2784 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2785 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2786 #if 1 2787 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2788 for (p = 0; p < 3; ++p) { 2789 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); 2790 } 2791 #endif 2792 supportNew[0] = (c - cStart)*8 + 1+4; 2793 supportNew[1] = (c - cStart)*8 + 2+4; 2794 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2795 #if 1 2796 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2797 for (p = 0; p < 2; ++p) { 2798 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); 2799 } 2800 #endif 2801 ++newp; 2802 } 2803 /* Split Edges have 2 vertices and the same faces as the parent */ 2804 for (e = eStart; e < eEnd; ++e) { 2805 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2806 2807 for (r = 0; r < 2; ++r) { 2808 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2809 const PetscInt *cone, *ornt, *support; 2810 PetscInt coneNew[2], coneSize, c, supportSize, s; 2811 2812 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2813 coneNew[0] = vStartNew + (cone[0] - vStart); 2814 coneNew[1] = vStartNew + (cone[1] - vStart); 2815 coneNew[(r+1)%2] = newv; 2816 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2817 #if 1 2818 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2819 for (p = 0; p < 2; ++p) { 2820 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); 2821 } 2822 #endif 2823 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2824 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2825 for (s = 0; s < supportSize; ++s) { 2826 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2827 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2828 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2829 for (c = 0; c < coneSize; ++c) { 2830 if (cone[c] == e) break; 2831 } 2832 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2833 } 2834 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2835 #if 1 2836 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2837 for (p = 0; p < supportSize; ++p) { 2838 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); 2839 } 2840 #endif 2841 } 2842 } 2843 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2844 for (f = fStart; f < fEnd; ++f) { 2845 const PetscInt *cone, *ornt, *support; 2846 PetscInt coneSize, supportSize, s; 2847 2848 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2849 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2850 for (r = 0; r < 3; ++r) { 2851 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2852 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2853 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2854 -1, -1, 1, 6, 0, 4, 2855 2, 5, 3, 4, -1, -1, 2856 -1, -1, 3, 6, 2, 7}; 2857 2858 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2859 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2860 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2861 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2862 #if 1 2863 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2864 for (p = 0; p < 2; ++p) { 2865 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); 2866 } 2867 #endif 2868 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2869 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2870 for (s = 0; s < supportSize; ++s) { 2871 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2872 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2873 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2874 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2875 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2876 er = GetTetSomethingInverse_Static(ornt[c], r); 2877 if (er == eint[c]) { 2878 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2879 } else { 2880 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2881 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2882 } 2883 } 2884 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2885 #if 1 2886 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2887 for (p = 0; p < intFaces; ++p) { 2888 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); 2889 } 2890 #endif 2891 } 2892 } 2893 /* Interior edges have 2 vertices and 4 faces */ 2894 for (c = cStart; c < cEnd; ++c) { 2895 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2896 const PetscInt *cone, *ornt, *fcone; 2897 PetscInt coneNew[2], supportNew[4], find; 2898 2899 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2900 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2901 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2902 find = GetTriEdge_Static(ornt[0], 0); 2903 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2904 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2905 find = GetTriEdge_Static(ornt[2], 1); 2906 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2907 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2908 #if 1 2909 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2910 for (p = 0; p < 2; ++p) { 2911 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); 2912 } 2913 #endif 2914 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2915 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2916 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2917 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2918 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2919 #if 1 2920 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2921 for (p = 0; p < 4; ++p) { 2922 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); 2923 } 2924 #endif 2925 } 2926 /* Old vertices have identical supports */ 2927 for (v = vStart; v < vEnd; ++v) { 2928 const PetscInt newp = vStartNew + (v - vStart); 2929 const PetscInt *support, *cone; 2930 PetscInt size, s; 2931 2932 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2933 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2934 for (s = 0; s < size; ++s) { 2935 PetscInt r = 0; 2936 2937 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2938 if (cone[1] == v) r = 1; 2939 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2940 } 2941 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2942 #if 1 2943 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2944 for (p = 0; p < size; ++p) { 2945 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); 2946 } 2947 #endif 2948 } 2949 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2950 for (e = eStart; e < eEnd; ++e) { 2951 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2952 const PetscInt *cone, *support; 2953 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2954 2955 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2956 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2957 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2958 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2959 for (s = 0; s < size; ++s) { 2960 PetscInt r = 0; 2961 2962 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2963 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2964 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2965 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2966 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2967 } 2968 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2969 for (s = 0; s < starSize*2; s += 2) { 2970 const PetscInt *cone, *ornt; 2971 PetscInt e01, e23; 2972 2973 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2974 /* Check edge 0-1 */ 2975 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2976 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2977 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2978 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2979 /* Check edge 2-3 */ 2980 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2981 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2982 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2983 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2984 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2985 } 2986 } 2987 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2988 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2989 #if 1 2990 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2991 for (p = 0; p < 2+size*2+cellSize; ++p) { 2992 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); 2993 } 2994 #endif 2995 } 2996 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2997 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2998 break; 2999 case REFINER_HYBRID_SIMPLEX_3D: 3000 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 3001 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3002 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3003 for (c = cStart; c < cMax; ++c) { 3004 const PetscInt newp = cStartNew + (c - cStart)*8; 3005 const PetscInt *cone, *ornt; 3006 PetscInt coneNew[4], orntNew[4]; 3007 3008 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3009 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3010 /* A tetrahedron: {0, a, c, d} */ 3011 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3012 orntNew[0] = ornt[0]; 3013 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3014 orntNew[1] = ornt[1]; 3015 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3016 orntNew[2] = ornt[2]; 3017 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3018 orntNew[3] = 0; 3019 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3020 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3021 #if 1 3022 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); 3023 for (p = 0; p < 4; ++p) { 3024 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); 3025 } 3026 #endif 3027 /* B tetrahedron: {a, 1, b, e} */ 3028 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3029 orntNew[0] = ornt[0]; 3030 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3031 orntNew[1] = ornt[1]; 3032 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3033 orntNew[2] = 0; 3034 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3035 orntNew[3] = ornt[3]; 3036 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3037 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3038 #if 1 3039 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); 3040 for (p = 0; p < 4; ++p) { 3041 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); 3042 } 3043 #endif 3044 /* C tetrahedron: {c, b, 2, f} */ 3045 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3046 orntNew[0] = ornt[0]; 3047 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3048 orntNew[1] = 0; 3049 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3050 orntNew[2] = ornt[2]; 3051 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3052 orntNew[3] = ornt[3]; 3053 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3054 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3055 #if 1 3056 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); 3057 for (p = 0; p < 4; ++p) { 3058 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); 3059 } 3060 #endif 3061 /* D tetrahedron: {d, e, f, 3} */ 3062 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3063 orntNew[0] = 0; 3064 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3065 orntNew[1] = ornt[1]; 3066 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3067 orntNew[2] = ornt[2]; 3068 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3069 orntNew[3] = ornt[3]; 3070 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3071 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3072 #if 1 3073 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); 3074 for (p = 0; p < 4; ++p) { 3075 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); 3076 } 3077 #endif 3078 /* A' tetrahedron: {d, a, c, f} */ 3079 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3080 orntNew[0] = -3; 3081 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3082 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 3083 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3084 orntNew[2] = 0; 3085 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3086 orntNew[3] = 2; 3087 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3088 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3089 #if 1 3090 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); 3091 for (p = 0; p < 4; ++p) { 3092 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); 3093 } 3094 #endif 3095 /* B' tetrahedron: {e, b, a, f} */ 3096 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3097 orntNew[0] = -3; 3098 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3099 orntNew[1] = 1; 3100 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3101 orntNew[2] = 0; 3102 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 3103 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 3104 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3105 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3106 #if 1 3107 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); 3108 for (p = 0; p < 4; ++p) { 3109 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); 3110 } 3111 #endif 3112 /* C' tetrahedron: {b, f, c, a} */ 3113 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3114 orntNew[0] = -3; 3115 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 3116 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 3117 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3118 orntNew[2] = -3; 3119 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3120 orntNew[3] = -2; 3121 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3122 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3123 #if 1 3124 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); 3125 for (p = 0; p < 4; ++p) { 3126 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 3127 } 3128 #endif 3129 /* D' tetrahedron: {f, e, d, a} */ 3130 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3131 orntNew[0] = -3; 3132 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3133 orntNew[1] = -3; 3134 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 3135 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 3136 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3137 orntNew[3] = -3; 3138 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3139 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3140 #if 1 3141 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); 3142 for (p = 0; p < 4; ++p) { 3143 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); 3144 } 3145 #endif 3146 } 3147 /* Hybrid cells have 5 faces */ 3148 for (c = cMax; c < cEnd; ++c) { 3149 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 3150 const PetscInt *cone, *ornt, *fornt; 3151 PetscInt coneNew[5], orntNew[5], o, of, i; 3152 3153 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3154 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3155 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 3156 o = ornt[0] < 0 ? -1 : 1; 3157 for (r = 0; r < 3; ++r) { 3158 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 3159 orntNew[0] = ornt[0]; 3160 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 3161 orntNew[1] = ornt[1]; 3162 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 3163 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 3164 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 3165 orntNew[i] = 0; 3166 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 3167 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 3168 orntNew[i] = 0; 3169 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 3170 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 3171 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); 3172 orntNew[i] = 0; 3173 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3174 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3175 #if 1 3176 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); 3177 for (p = 0; p < 2; ++p) { 3178 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); 3179 } 3180 for (p = 2; p < 5; ++p) { 3181 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); 3182 } 3183 #endif 3184 } 3185 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 3186 orntNew[0] = 0; 3187 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3188 orntNew[1] = 0; 3189 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3190 orntNew[2] = 0; 3191 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3192 orntNew[3] = 0; 3193 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3194 orntNew[4] = 0; 3195 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3196 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3197 #if 1 3198 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); 3199 for (p = 0; p < 2; ++p) { 3200 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); 3201 } 3202 for (p = 2; p < 5; ++p) { 3203 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); 3204 } 3205 #endif 3206 } 3207 /* Split faces have 3 edges and the same cells as the parent */ 3208 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3209 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3210 for (f = fStart; f < fMax; ++f) { 3211 const PetscInt newp = fStartNew + (f - fStart)*4; 3212 const PetscInt *cone, *ornt, *support; 3213 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3214 3215 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3216 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3217 /* A triangle */ 3218 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3219 orntNew[0] = ornt[0]; 3220 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3221 orntNew[1] = -2; 3222 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3223 orntNew[2] = ornt[2]; 3224 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3225 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3226 #if 1 3227 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); 3228 for (p = 0; p < 3; ++p) { 3229 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); 3230 } 3231 #endif 3232 /* B triangle */ 3233 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3234 orntNew[0] = ornt[0]; 3235 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3236 orntNew[1] = ornt[1]; 3237 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3238 orntNew[2] = -2; 3239 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3240 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3241 #if 1 3242 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); 3243 for (p = 0; p < 3; ++p) { 3244 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); 3245 } 3246 #endif 3247 /* C triangle */ 3248 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3249 orntNew[0] = -2; 3250 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3251 orntNew[1] = ornt[1]; 3252 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3253 orntNew[2] = ornt[2]; 3254 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3255 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3256 #if 1 3257 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); 3258 for (p = 0; p < 3; ++p) { 3259 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); 3260 } 3261 #endif 3262 /* D triangle */ 3263 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3264 orntNew[0] = 0; 3265 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3266 orntNew[1] = 0; 3267 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3268 orntNew[2] = 0; 3269 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3270 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3271 #if 1 3272 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); 3273 for (p = 0; p < 3; ++p) { 3274 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); 3275 } 3276 #endif 3277 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3278 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3279 for (r = 0; r < 4; ++r) { 3280 for (s = 0; s < supportSize; ++s) { 3281 PetscInt subf; 3282 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3283 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3284 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3285 for (c = 0; c < coneSize; ++c) { 3286 if (cone[c] == f) break; 3287 } 3288 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3289 if (support[s] < cMax) { 3290 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3291 } else { 3292 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3293 } 3294 } 3295 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3296 #if 1 3297 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); 3298 for (p = 0; p < supportSize; ++p) { 3299 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); 3300 } 3301 #endif 3302 } 3303 } 3304 /* Interior cell faces have 3 edges and 2 cells */ 3305 for (c = cStart; c < cMax; ++c) { 3306 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3307 const PetscInt *cone, *ornt; 3308 PetscInt coneNew[3], orntNew[3]; 3309 PetscInt supportNew[2]; 3310 3311 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3312 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3313 /* Face A: {c, a, d} */ 3314 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3315 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3316 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3317 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3318 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 3319 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3320 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3321 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3322 #if 1 3323 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3324 for (p = 0; p < 3; ++p) { 3325 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); 3326 } 3327 #endif 3328 supportNew[0] = (c - cStart)*8 + 0; 3329 supportNew[1] = (c - cStart)*8 + 0+4; 3330 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3331 #if 1 3332 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3333 for (p = 0; p < 2; ++p) { 3334 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); 3335 } 3336 #endif 3337 ++newp; 3338 /* Face B: {a, b, e} */ 3339 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3340 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3341 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 3342 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3343 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3344 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3345 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3346 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3347 #if 1 3348 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); 3349 for (p = 0; p < 3; ++p) { 3350 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); 3351 } 3352 #endif 3353 supportNew[0] = (c - cStart)*8 + 1; 3354 supportNew[1] = (c - cStart)*8 + 1+4; 3355 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3356 #if 1 3357 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3358 for (p = 0; p < 2; ++p) { 3359 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); 3360 } 3361 #endif 3362 ++newp; 3363 /* Face C: {c, f, b} */ 3364 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3365 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3366 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3367 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3368 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 3369 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3370 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3371 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3372 #if 1 3373 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3374 for (p = 0; p < 3; ++p) { 3375 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); 3376 } 3377 #endif 3378 supportNew[0] = (c - cStart)*8 + 2; 3379 supportNew[1] = (c - cStart)*8 + 2+4; 3380 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3381 #if 1 3382 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3383 for (p = 0; p < 2; ++p) { 3384 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); 3385 } 3386 #endif 3387 ++newp; 3388 /* Face D: {d, e, f} */ 3389 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 3390 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3391 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3392 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3393 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3394 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3395 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3396 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3397 #if 1 3398 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3399 for (p = 0; p < 3; ++p) { 3400 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); 3401 } 3402 #endif 3403 supportNew[0] = (c - cStart)*8 + 3; 3404 supportNew[1] = (c - cStart)*8 + 3+4; 3405 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3406 #if 1 3407 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3408 for (p = 0; p < 2; ++p) { 3409 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); 3410 } 3411 #endif 3412 ++newp; 3413 /* Face E: {d, f, a} */ 3414 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3415 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3416 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3417 orntNew[1] = -2; 3418 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3419 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3420 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3421 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3422 #if 1 3423 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3424 for (p = 0; p < 3; ++p) { 3425 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); 3426 } 3427 #endif 3428 supportNew[0] = (c - cStart)*8 + 0+4; 3429 supportNew[1] = (c - cStart)*8 + 3+4; 3430 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3431 #if 1 3432 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3433 for (p = 0; p < 2; ++p) { 3434 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); 3435 } 3436 #endif 3437 ++newp; 3438 /* Face F: {c, a, f} */ 3439 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3440 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3441 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3442 orntNew[1] = 0; 3443 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3444 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3445 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3446 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3447 #if 1 3448 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3449 for (p = 0; p < 3; ++p) { 3450 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); 3451 } 3452 #endif 3453 supportNew[0] = (c - cStart)*8 + 0+4; 3454 supportNew[1] = (c - cStart)*8 + 2+4; 3455 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3456 #if 1 3457 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3458 for (p = 0; p < 2; ++p) { 3459 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); 3460 } 3461 #endif 3462 ++newp; 3463 /* Face G: {e, a, f} */ 3464 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3465 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3466 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3467 orntNew[1] = 0; 3468 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3469 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3470 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3471 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3472 #if 1 3473 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3474 for (p = 0; p < 3; ++p) { 3475 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); 3476 } 3477 #endif 3478 supportNew[0] = (c - cStart)*8 + 1+4; 3479 supportNew[1] = (c - cStart)*8 + 3+4; 3480 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3481 #if 1 3482 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3483 for (p = 0; p < 2; ++p) { 3484 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); 3485 } 3486 #endif 3487 ++newp; 3488 /* Face H: {a, b, f} */ 3489 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3490 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3491 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3492 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3493 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3494 orntNew[2] = -2; 3495 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3496 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3497 #if 1 3498 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3499 for (p = 0; p < 3; ++p) { 3500 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); 3501 } 3502 #endif 3503 supportNew[0] = (c - cStart)*8 + 1+4; 3504 supportNew[1] = (c - cStart)*8 + 2+4; 3505 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3506 #if 1 3507 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3508 for (p = 0; p < 2; ++p) { 3509 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); 3510 } 3511 #endif 3512 ++newp; 3513 } 3514 /* Hybrid split faces have 4 edges and same cells */ 3515 for (f = fMax; f < fEnd; ++f) { 3516 const PetscInt *cone, *ornt, *support; 3517 PetscInt coneNew[4], orntNew[4]; 3518 PetscInt supportNew[2], size, s, c; 3519 3520 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3521 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3522 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3523 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3524 for (r = 0; r < 2; ++r) { 3525 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3526 3527 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3528 orntNew[0] = ornt[0]; 3529 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3530 orntNew[1] = ornt[1]; 3531 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3532 orntNew[2+r] = 0; 3533 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3534 orntNew[3-r] = 0; 3535 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3536 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3537 #if 1 3538 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3539 for (p = 0; p < 2; ++p) { 3540 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); 3541 } 3542 for (p = 2; p < 4; ++p) { 3543 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); 3544 } 3545 #endif 3546 for (s = 0; s < size; ++s) { 3547 const PetscInt *coneCell, *orntCell, *fornt; 3548 PetscInt o, of; 3549 3550 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3551 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3552 o = orntCell[0] < 0 ? -1 : 1; 3553 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3554 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3555 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3556 of = fornt[c-2] < 0 ? -1 : 1; 3557 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3558 } 3559 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3560 #if 1 3561 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3562 for (p = 0; p < size; ++p) { 3563 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); 3564 } 3565 #endif 3566 } 3567 } 3568 /* Hybrid cell faces have 4 edges and 2 cells */ 3569 for (c = cMax; c < cEnd; ++c) { 3570 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3571 const PetscInt *cone, *ornt; 3572 PetscInt coneNew[4], orntNew[4]; 3573 PetscInt supportNew[2]; 3574 3575 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3576 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3577 for (r = 0; r < 3; ++r) { 3578 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3579 orntNew[0] = 0; 3580 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3581 orntNew[1] = 0; 3582 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3583 orntNew[2] = 0; 3584 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3585 orntNew[3] = 0; 3586 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3587 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3588 #if 1 3589 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); 3590 for (p = 0; p < 2; ++p) { 3591 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); 3592 } 3593 for (p = 2; p < 4; ++p) { 3594 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); 3595 } 3596 #endif 3597 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3598 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3599 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3600 #if 1 3601 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); 3602 for (p = 0; p < 2; ++p) { 3603 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); 3604 } 3605 #endif 3606 } 3607 } 3608 /* Interior split edges have 2 vertices and the same faces as the parent */ 3609 for (e = eStart; e < eMax; ++e) { 3610 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3611 3612 for (r = 0; r < 2; ++r) { 3613 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3614 const PetscInt *cone, *ornt, *support; 3615 PetscInt coneNew[2], coneSize, c, supportSize, s; 3616 3617 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3618 coneNew[0] = vStartNew + (cone[0] - vStart); 3619 coneNew[1] = vStartNew + (cone[1] - vStart); 3620 coneNew[(r+1)%2] = newv; 3621 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3622 #if 1 3623 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3624 for (p = 0; p < 2; ++p) { 3625 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); 3626 } 3627 #endif 3628 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3629 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3630 for (s = 0; s < supportSize; ++s) { 3631 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3632 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3633 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3634 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3635 if (support[s] < fMax) { 3636 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3637 } else { 3638 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3639 } 3640 } 3641 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3642 #if 1 3643 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3644 for (p = 0; p < supportSize; ++p) { 3645 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); 3646 } 3647 #endif 3648 } 3649 } 3650 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3651 for (f = fStart; f < fMax; ++f) { 3652 const PetscInt *cone, *ornt, *support; 3653 PetscInt coneSize, supportSize, s; 3654 3655 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3656 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3657 for (r = 0; r < 3; ++r) { 3658 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3659 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3660 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3661 -1, -1, 1, 6, 0, 4, 3662 2, 5, 3, 4, -1, -1, 3663 -1, -1, 3, 6, 2, 7}; 3664 3665 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3666 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3667 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3668 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3669 #if 1 3670 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3671 for (p = 0; p < 2; ++p) { 3672 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); 3673 } 3674 #endif 3675 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3676 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3677 for (s = 0; s < supportSize; ++s) { 3678 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3679 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3680 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3681 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3682 if (support[s] < cMax) { 3683 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3684 er = GetTetSomethingInverse_Static(ornt[c], r); 3685 if (er == eint[c]) { 3686 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3687 } else { 3688 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3689 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3690 } 3691 } else { 3692 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 3693 } 3694 } 3695 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3696 #if 1 3697 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3698 for (p = 0; p < intFaces; ++p) { 3699 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); 3700 } 3701 #endif 3702 } 3703 } 3704 /* Interior cell edges have 2 vertices and 4 faces */ 3705 for (c = cStart; c < cMax; ++c) { 3706 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3707 const PetscInt *cone, *ornt, *fcone; 3708 PetscInt coneNew[2], supportNew[4], find; 3709 3710 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3711 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3712 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3713 find = GetTriEdge_Static(ornt[0], 0); 3714 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3715 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3716 find = GetTriEdge_Static(ornt[2], 1); 3717 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3718 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3719 #if 1 3720 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3721 for (p = 0; p < 2; ++p) { 3722 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); 3723 } 3724 #endif 3725 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3726 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3727 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3728 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3729 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3730 #if 1 3731 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3732 for (p = 0; p < 4; ++p) { 3733 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); 3734 } 3735 #endif 3736 } 3737 /* Hybrid edges have two vertices and the same faces */ 3738 for (e = eMax; e < eEnd; ++e) { 3739 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3740 const PetscInt *cone, *support, *fcone; 3741 PetscInt coneNew[2], size, fsize, s; 3742 3743 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3744 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3745 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3746 coneNew[0] = vStartNew + (cone[0] - vStart); 3747 coneNew[1] = vStartNew + (cone[1] - vStart); 3748 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3749 #if 1 3750 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3751 for (p = 0; p < 2; ++p) { 3752 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); 3753 } 3754 #endif 3755 for (s = 0; s < size; ++s) { 3756 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3757 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3758 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3759 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3760 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3761 } 3762 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3763 #if 1 3764 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3765 for (p = 0; p < size; ++p) { 3766 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); 3767 } 3768 #endif 3769 } 3770 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3771 for (f = fMax; f < fEnd; ++f) { 3772 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3773 const PetscInt *cone, *support, *ccone, *cornt; 3774 PetscInt coneNew[2], size, csize, s; 3775 3776 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3777 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3778 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3779 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3780 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3781 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3782 #if 1 3783 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3784 for (p = 0; p < 2; ++p) { 3785 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); 3786 } 3787 #endif 3788 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3789 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3790 for (s = 0; s < size; ++s) { 3791 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3792 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3793 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3794 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3795 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]); 3796 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 3797 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 3798 } 3799 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3800 #if 1 3801 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3802 for (p = 0; p < 2+size*2; ++p) { 3803 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); 3804 } 3805 #endif 3806 } 3807 /* Interior vertices have identical supports */ 3808 for (v = vStart; v < vEnd; ++v) { 3809 const PetscInt newp = vStartNew + (v - vStart); 3810 const PetscInt *support, *cone; 3811 PetscInt size, s; 3812 3813 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3814 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3815 for (s = 0; s < size; ++s) { 3816 PetscInt r = 0; 3817 3818 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3819 if (cone[1] == v) r = 1; 3820 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3821 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3822 } 3823 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3824 #if 1 3825 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3826 for (p = 0; p < size; ++p) { 3827 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); 3828 } 3829 #endif 3830 } 3831 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3832 for (e = eStart; e < eMax; ++e) { 3833 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3834 const PetscInt *cone, *support; 3835 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3836 3837 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3838 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3839 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3840 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3841 for (s = 0; s < size; ++s) { 3842 PetscInt r = 0; 3843 3844 if (support[s] < fMax) { 3845 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3846 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3847 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3848 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3849 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3850 faceSize += 2; 3851 } else { 3852 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3853 ++faceSize; 3854 } 3855 } 3856 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3857 for (s = 0; s < starSize*2; s += 2) { 3858 const PetscInt *cone, *ornt; 3859 PetscInt e01, e23; 3860 3861 if ((star[s] >= cStart) && (star[s] < cMax)) { 3862 /* Check edge 0-1 */ 3863 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3864 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3865 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3866 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3867 /* Check edge 2-3 */ 3868 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3869 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3870 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3871 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3872 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3873 } 3874 } 3875 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3876 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3877 #if 1 3878 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3879 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3880 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); 3881 } 3882 #endif 3883 } 3884 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3885 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3886 break; 3887 case REFINER_HEX_3D: 3888 /* 3889 Bottom (viewed from top) Top 3890 1---------2---------2 7---------2---------6 3891 | | | | | | 3892 | B 2 C | | H 2 G | 3893 | | | | | | 3894 3----3----0----1----1 3----3----0----1----1 3895 | | | | | | 3896 | A 0 D | | E 0 F | 3897 | | | | | | 3898 0---------0---------3 4---------0---------5 3899 */ 3900 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3901 for (c = cStart; c < cEnd; ++c) { 3902 const PetscInt newp = (c - cStart)*8; 3903 const PetscInt *cone, *ornt; 3904 PetscInt coneNew[6], orntNew[6]; 3905 3906 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3907 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3908 /* A hex */ 3909 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3910 orntNew[0] = ornt[0]; 3911 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3912 orntNew[1] = 0; 3913 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3914 orntNew[2] = ornt[2]; 3915 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3916 orntNew[3] = 0; 3917 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3918 orntNew[4] = 0; 3919 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3920 orntNew[5] = ornt[5]; 3921 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3922 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3923 #if 1 3924 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); 3925 for (p = 0; p < 6; ++p) { 3926 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); 3927 } 3928 #endif 3929 /* B hex */ 3930 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3931 orntNew[0] = ornt[0]; 3932 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3933 orntNew[1] = 0; 3934 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3935 orntNew[2] = -1; 3936 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3937 orntNew[3] = ornt[3]; 3938 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3939 orntNew[4] = 0; 3940 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3941 orntNew[5] = ornt[5]; 3942 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3943 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3944 #if 1 3945 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); 3946 for (p = 0; p < 6; ++p) { 3947 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); 3948 } 3949 #endif 3950 /* C hex */ 3951 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3952 orntNew[0] = ornt[0]; 3953 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3954 orntNew[1] = 0; 3955 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3956 orntNew[2] = -1; 3957 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3958 orntNew[3] = ornt[3]; 3959 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3960 orntNew[4] = ornt[4]; 3961 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3962 orntNew[5] = -4; 3963 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3964 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3965 #if 1 3966 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); 3967 for (p = 0; p < 6; ++p) { 3968 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); 3969 } 3970 #endif 3971 /* D hex */ 3972 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3973 orntNew[0] = ornt[0]; 3974 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3975 orntNew[1] = 0; 3976 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3977 orntNew[2] = ornt[2]; 3978 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3979 orntNew[3] = 0; 3980 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3981 orntNew[4] = ornt[4]; 3982 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3983 orntNew[5] = -4; 3984 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3985 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3986 #if 1 3987 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); 3988 for (p = 0; p < 6; ++p) { 3989 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); 3990 } 3991 #endif 3992 /* E hex */ 3993 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3994 orntNew[0] = -4; 3995 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3996 orntNew[1] = ornt[1]; 3997 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3998 orntNew[2] = ornt[2]; 3999 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4000 orntNew[3] = 0; 4001 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4002 orntNew[4] = -1; 4003 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4004 orntNew[5] = ornt[5]; 4005 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4006 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4007 #if 1 4008 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); 4009 for (p = 0; p < 6; ++p) { 4010 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); 4011 } 4012 #endif 4013 /* F hex */ 4014 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4015 orntNew[0] = -4; 4016 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4017 orntNew[1] = ornt[1]; 4018 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4019 orntNew[2] = ornt[2]; 4020 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4021 orntNew[3] = -1; 4022 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4023 orntNew[4] = ornt[4]; 4024 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4025 orntNew[5] = 1; 4026 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4027 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4028 #if 1 4029 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); 4030 for (p = 0; p < 6; ++p) { 4031 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); 4032 } 4033 #endif 4034 /* G hex */ 4035 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4036 orntNew[0] = -4; 4037 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4038 orntNew[1] = ornt[1]; 4039 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4040 orntNew[2] = 0; 4041 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4042 orntNew[3] = ornt[3]; 4043 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4044 orntNew[4] = ornt[4]; 4045 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4046 orntNew[5] = -3; 4047 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4048 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4049 #if 1 4050 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); 4051 for (p = 0; p < 6; ++p) { 4052 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); 4053 } 4054 #endif 4055 /* H hex */ 4056 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4057 orntNew[0] = -4; 4058 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4059 orntNew[1] = ornt[1]; 4060 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4061 orntNew[2] = -1; 4062 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4063 orntNew[3] = ornt[3]; 4064 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4065 orntNew[4] = 3; 4066 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4067 orntNew[5] = ornt[5]; 4068 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4069 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4070 #if 1 4071 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); 4072 for (p = 0; p < 6; ++p) { 4073 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); 4074 } 4075 #endif 4076 } 4077 /* Split faces have 4 edges and the same cells as the parent */ 4078 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4079 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4080 for (f = fStart; f < fEnd; ++f) { 4081 for (r = 0; r < 4; ++r) { 4082 /* TODO: This can come from GetFaces_Internal() */ 4083 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}; 4084 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4085 const PetscInt *cone, *ornt, *support; 4086 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4087 4088 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4089 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4090 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4091 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4092 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4093 orntNew[(r+0)%4] = ornt[r]; 4094 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4095 orntNew[(r+1)%4] = 0; 4096 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4097 orntNew[(r+2)%4] = -2; 4098 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4099 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4100 #if 1 4101 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4102 for (p = 0; p < 4; ++p) { 4103 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); 4104 } 4105 #endif 4106 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4107 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4108 for (s = 0; s < supportSize; ++s) { 4109 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4110 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4111 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4112 for (c = 0; c < coneSize; ++c) { 4113 if (cone[c] == f) break; 4114 } 4115 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 4116 } 4117 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4118 #if 1 4119 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4120 for (p = 0; p < supportSize; ++p) { 4121 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); 4122 } 4123 #endif 4124 } 4125 } 4126 /* Interior faces have 4 edges and 2 cells */ 4127 for (c = cStart; c < cEnd; ++c) { 4128 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}; 4129 const PetscInt *cone, *ornt; 4130 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4131 4132 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4133 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4134 /* A-D face */ 4135 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 4136 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4137 orntNew[0] = 0; 4138 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4139 orntNew[1] = 0; 4140 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4141 orntNew[2] = -2; 4142 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 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 /* C-D face */ 4153 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 4154 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4155 orntNew[0] = 0; 4156 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4157 orntNew[1] = 0; 4158 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4159 orntNew[2] = -2; 4160 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 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 /* B-C face */ 4171 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 4172 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4173 orntNew[0] = -2; 4174 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4175 orntNew[1] = 0; 4176 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4177 orntNew[2] = 0; 4178 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4179 orntNew[3] = -2; 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 /* A-B face */ 4189 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 4190 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4191 orntNew[0] = -2; 4192 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4193 orntNew[1] = 0; 4194 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4195 orntNew[2] = 0; 4196 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4197 orntNew[3] = -2; 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 /* E-F face */ 4207 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 4208 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4209 orntNew[0] = -2; 4210 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4211 orntNew[1] = -2; 4212 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4213 orntNew[2] = 0; 4214 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4215 orntNew[3] = 0; 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 /* F-G face */ 4225 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 4226 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4227 orntNew[0] = -2; 4228 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4229 orntNew[1] = -2; 4230 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 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 /* G-H face */ 4243 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 4244 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4245 orntNew[0] = -2; 4246 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4247 orntNew[1] = 0; 4248 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4249 orntNew[2] = 0; 4250 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 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 /* E-H face */ 4261 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 4262 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4263 orntNew[0] = -2; 4264 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4265 orntNew[1] = -2; 4266 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4267 orntNew[2] = 0; 4268 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4269 orntNew[3] = 0; 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 /* A-E face */ 4279 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 4280 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4281 orntNew[0] = 0; 4282 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4283 orntNew[1] = 0; 4284 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4285 orntNew[2] = -2; 4286 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4287 orntNew[3] = -2; 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 /* D-F face */ 4297 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 4298 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4299 orntNew[0] = -2; 4300 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4301 orntNew[1] = 0; 4302 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4303 orntNew[2] = 0; 4304 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4305 orntNew[3] = -2; 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 /* C-G face */ 4315 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 4316 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4317 orntNew[0] = -2; 4318 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4319 orntNew[1] = -2; 4320 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4321 orntNew[2] = 0; 4322 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4323 orntNew[3] = 0; 4324 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4325 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4326 #if 1 4327 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4328 for (p = 0; p < 4; ++p) { 4329 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 4330 } 4331 #endif 4332 /* B-H face */ 4333 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 4334 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4335 orntNew[0] = 0; 4336 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4337 orntNew[1] = -2; 4338 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4339 orntNew[2] = -2; 4340 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4341 orntNew[3] = 0; 4342 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4343 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4344 #if 1 4345 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4346 for (p = 0; p < 4; ++p) { 4347 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); 4348 } 4349 #endif 4350 for (r = 0; r < 12; ++r) { 4351 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 4352 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4353 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4354 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4355 #if 1 4356 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4357 for (p = 0; p < 2; ++p) { 4358 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); 4359 } 4360 #endif 4361 } 4362 } 4363 /* Split edges have 2 vertices and the same faces as the parent */ 4364 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4365 for (e = eStart; e < eEnd; ++e) { 4366 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4367 4368 for (r = 0; r < 2; ++r) { 4369 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4370 const PetscInt *cone, *ornt, *support; 4371 PetscInt coneNew[2], coneSize, c, supportSize, s; 4372 4373 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4374 coneNew[0] = vStartNew + (cone[0] - vStart); 4375 coneNew[1] = vStartNew + (cone[1] - vStart); 4376 coneNew[(r+1)%2] = newv; 4377 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4378 #if 1 4379 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4380 for (p = 0; p < 2; ++p) { 4381 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); 4382 } 4383 #endif 4384 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4385 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4386 for (s = 0; s < supportSize; ++s) { 4387 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4388 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4389 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4390 for (c = 0; c < coneSize; ++c) { 4391 if (cone[c] == e) break; 4392 } 4393 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 4394 } 4395 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4396 #if 1 4397 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4398 for (p = 0; p < supportSize; ++p) { 4399 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); 4400 } 4401 #endif 4402 } 4403 } 4404 /* Face edges have 2 vertices and 2+cells faces */ 4405 for (f = fStart; f < fEnd; ++f) { 4406 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}; 4407 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4408 const PetscInt *cone, *coneCell, *orntCell, *support; 4409 PetscInt coneNew[2], coneSize, c, supportSize, s; 4410 4411 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4412 for (r = 0; r < 4; ++r) { 4413 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4414 4415 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4416 coneNew[1] = newv; 4417 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4418 #if 1 4419 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4420 for (p = 0; p < 2; ++p) { 4421 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); 4422 } 4423 #endif 4424 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4425 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4426 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4427 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4428 for (s = 0; s < supportSize; ++s) { 4429 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4430 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4431 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4432 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4433 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4434 } 4435 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4436 #if 1 4437 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4438 for (p = 0; p < 2+supportSize; ++p) { 4439 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); 4440 } 4441 #endif 4442 } 4443 } 4444 /* Cell edges have 2 vertices and 4 faces */ 4445 for (c = cStart; c < cEnd; ++c) { 4446 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}; 4447 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4448 const PetscInt *cone; 4449 PetscInt coneNew[2], supportNew[4]; 4450 4451 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4452 for (r = 0; r < 6; ++r) { 4453 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4454 4455 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4456 coneNew[1] = newv; 4457 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4458 #if 1 4459 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4460 for (p = 0; p < 2; ++p) { 4461 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); 4462 } 4463 #endif 4464 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4465 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4466 #if 1 4467 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4468 for (p = 0; p < 4; ++p) { 4469 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); 4470 } 4471 #endif 4472 } 4473 } 4474 /* Old vertices have identical supports */ 4475 for (v = vStart; v < vEnd; ++v) { 4476 const PetscInt newp = vStartNew + (v - vStart); 4477 const PetscInt *support, *cone; 4478 PetscInt size, s; 4479 4480 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4481 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4482 for (s = 0; s < size; ++s) { 4483 PetscInt r = 0; 4484 4485 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4486 if (cone[1] == v) r = 1; 4487 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4488 } 4489 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4490 #if 1 4491 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4492 for (p = 0; p < size; ++p) { 4493 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); 4494 } 4495 #endif 4496 } 4497 /* Edge vertices have 2 + faces supports */ 4498 for (e = eStart; e < eEnd; ++e) { 4499 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4500 const PetscInt *cone, *support; 4501 PetscInt size, s; 4502 4503 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4504 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4505 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4506 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4507 for (s = 0; s < size; ++s) { 4508 PetscInt r; 4509 4510 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4511 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4512 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 4513 } 4514 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4515 #if 1 4516 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4517 for (p = 0; p < 2+size; ++p) { 4518 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); 4519 } 4520 #endif 4521 } 4522 /* Face vertices have 4 + cells supports */ 4523 for (f = fStart; f < fEnd; ++f) { 4524 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4525 const PetscInt *cone, *support; 4526 PetscInt size, s; 4527 4528 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4529 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4530 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4531 for (s = 0; s < size; ++s) { 4532 PetscInt r; 4533 4534 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4535 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4536 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 4537 } 4538 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4539 #if 1 4540 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4541 for (p = 0; p < 4+size; ++p) { 4542 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); 4543 } 4544 #endif 4545 } 4546 /* Cell vertices have 6 supports */ 4547 for (c = cStart; c < cEnd; ++c) { 4548 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4549 PetscInt supportNew[6]; 4550 4551 for (r = 0; r < 6; ++r) { 4552 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4553 } 4554 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4555 } 4556 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4557 break; 4558 case REFINER_HYBRID_HEX_3D: 4559 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4560 /* 4561 Bottom (viewed from top) Top 4562 1---------2---------2 7---------2---------6 4563 | | | | | | 4564 | B 2 C | | H 2 G | 4565 | | | | | | 4566 3----3----0----1----1 3----3----0----1----1 4567 | | | | | | 4568 | A 0 D | | E 0 F | 4569 | | | | | | 4570 0---------0---------3 4---------0---------5 4571 */ 4572 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4573 for (c = cStart; c < cMax; ++c) { 4574 const PetscInt newp = (c - cStart)*8; 4575 const PetscInt *cone, *ornt; 4576 PetscInt coneNew[6], orntNew[6]; 4577 4578 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4579 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4580 /* A hex */ 4581 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4582 orntNew[0] = ornt[0]; 4583 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4584 orntNew[1] = 0; 4585 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4586 orntNew[2] = ornt[2]; 4587 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4588 orntNew[3] = 0; 4589 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4590 orntNew[4] = 0; 4591 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4592 orntNew[5] = ornt[5]; 4593 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4594 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4595 #if 1 4596 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); 4597 for (p = 0; p < 6; ++p) { 4598 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); 4599 } 4600 #endif 4601 /* B hex */ 4602 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4603 orntNew[0] = ornt[0]; 4604 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4605 orntNew[1] = 0; 4606 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4607 orntNew[2] = -1; 4608 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4609 orntNew[3] = ornt[3]; 4610 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4611 orntNew[4] = 0; 4612 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4613 orntNew[5] = ornt[5]; 4614 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4615 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4616 #if 1 4617 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); 4618 for (p = 0; p < 6; ++p) { 4619 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); 4620 } 4621 #endif 4622 /* C hex */ 4623 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4624 orntNew[0] = ornt[0]; 4625 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4626 orntNew[1] = 0; 4627 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4628 orntNew[2] = -1; 4629 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4630 orntNew[3] = ornt[3]; 4631 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4632 orntNew[4] = ornt[4]; 4633 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4634 orntNew[5] = -4; 4635 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4636 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4637 #if 1 4638 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); 4639 for (p = 0; p < 6; ++p) { 4640 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); 4641 } 4642 #endif 4643 /* D hex */ 4644 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4645 orntNew[0] = ornt[0]; 4646 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4647 orntNew[1] = 0; 4648 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4649 orntNew[2] = ornt[2]; 4650 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4651 orntNew[3] = 0; 4652 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4653 orntNew[4] = ornt[4]; 4654 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4655 orntNew[5] = -4; 4656 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4657 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4658 #if 1 4659 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); 4660 for (p = 0; p < 6; ++p) { 4661 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); 4662 } 4663 #endif 4664 /* E hex */ 4665 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4666 orntNew[0] = -4; 4667 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4668 orntNew[1] = ornt[1]; 4669 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4670 orntNew[2] = ornt[2]; 4671 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4672 orntNew[3] = 0; 4673 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4674 orntNew[4] = -1; 4675 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4676 orntNew[5] = ornt[5]; 4677 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4678 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4679 #if 1 4680 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); 4681 for (p = 0; p < 6; ++p) { 4682 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); 4683 } 4684 #endif 4685 /* F hex */ 4686 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4687 orntNew[0] = -4; 4688 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4689 orntNew[1] = ornt[1]; 4690 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4691 orntNew[2] = ornt[2]; 4692 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4693 orntNew[3] = -1; 4694 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4695 orntNew[4] = ornt[4]; 4696 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4697 orntNew[5] = 1; 4698 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4699 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4700 #if 1 4701 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); 4702 for (p = 0; p < 6; ++p) { 4703 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); 4704 } 4705 #endif 4706 /* G hex */ 4707 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4708 orntNew[0] = -4; 4709 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4710 orntNew[1] = ornt[1]; 4711 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4712 orntNew[2] = 0; 4713 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4714 orntNew[3] = ornt[3]; 4715 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4716 orntNew[4] = ornt[4]; 4717 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4718 orntNew[5] = -3; 4719 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4720 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4721 #if 1 4722 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); 4723 for (p = 0; p < 6; ++p) { 4724 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); 4725 } 4726 #endif 4727 /* H hex */ 4728 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4729 orntNew[0] = -4; 4730 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4731 orntNew[1] = ornt[1]; 4732 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4733 orntNew[2] = -1; 4734 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4735 orntNew[3] = ornt[3]; 4736 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4737 orntNew[4] = 3; 4738 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4739 orntNew[5] = ornt[5]; 4740 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4741 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4742 #if 1 4743 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); 4744 for (p = 0; p < 6; ++p) { 4745 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); 4746 } 4747 #endif 4748 } 4749 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4750 /* 4751 3---------2---------2 4752 | | | 4753 | D 2 C | 4754 | | | 4755 3----3----0----1----1 4756 | | | 4757 | A 0 B | 4758 | | | 4759 0---------0---------1 4760 */ 4761 for (c = cMax; c < cEnd; ++c) { 4762 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4763 const PetscInt *cone, *ornt, *fornt; 4764 PetscInt coneNew[6], orntNew[6], o, of, i; 4765 4766 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4767 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4768 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4769 o = ornt[0] < 0 ? -1 : 1; 4770 for (r = 0; r < 4; ++r) { 4771 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4772 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4773 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 4774 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]); 4775 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4776 orntNew[0] = ornt[0]; 4777 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4778 orntNew[1] = ornt[0]; 4779 of = fornt[edgeA] < 0 ? -1 : 1; 4780 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 4781 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 4782 orntNew[i] = ornt[edgeA]; 4783 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 4784 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4785 orntNew[i] = 0; 4786 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 4787 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4788 orntNew[i] = -2; 4789 of = fornt[edgeB] < 0 ? -1 : 1; 4790 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 4791 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 4792 orntNew[i] = ornt[edgeB]; 4793 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4794 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4795 #if 1 4796 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); 4797 for (p = 0; p < 2; ++p) { 4798 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); 4799 } 4800 for (p = 2; p < 6; ++p) { 4801 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); 4802 } 4803 #endif 4804 } 4805 } 4806 /* Interior split faces have 4 edges and the same cells as the parent */ 4807 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4808 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4809 for (f = fStart; f < fMax; ++f) { 4810 for (r = 0; r < 4; ++r) { 4811 /* TODO: This can come from GetFaces_Internal() */ 4812 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}; 4813 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4814 const PetscInt *cone, *ornt, *support; 4815 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4816 4817 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4818 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4819 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4820 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4821 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4822 orntNew[(r+0)%4] = ornt[r]; 4823 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4824 orntNew[(r+1)%4] = 0; 4825 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4826 orntNew[(r+2)%4] = -2; 4827 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4828 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4829 #if 1 4830 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4831 for (p = 0; p < 4; ++p) { 4832 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4833 } 4834 #endif 4835 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4836 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4837 for (s = 0; s < supportSize; ++s) { 4838 PetscInt subf; 4839 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4840 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4841 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4842 for (c = 0; c < coneSize; ++c) { 4843 if (cone[c] == f) break; 4844 } 4845 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4846 if (support[s] < cMax) { 4847 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4848 } else { 4849 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4850 } 4851 } 4852 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4853 #if 1 4854 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4855 for (p = 0; p < supportSize; ++p) { 4856 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); 4857 } 4858 #endif 4859 } 4860 } 4861 /* Interior cell faces have 4 edges and 2 cells */ 4862 for (c = cStart; c < cMax; ++c) { 4863 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}; 4864 const PetscInt *cone, *ornt; 4865 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4866 4867 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4868 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4869 /* A-D face */ 4870 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4871 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4872 orntNew[0] = 0; 4873 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4874 orntNew[1] = 0; 4875 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4876 orntNew[2] = -2; 4877 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 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 /* C-D face */ 4888 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4889 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4890 orntNew[0] = 0; 4891 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4892 orntNew[1] = 0; 4893 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4894 orntNew[2] = -2; 4895 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 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 /* B-C face */ 4906 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4907 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4908 orntNew[0] = -2; 4909 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4910 orntNew[1] = 0; 4911 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4912 orntNew[2] = 0; 4913 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4914 orntNew[3] = -2; 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 /* A-B face */ 4924 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4925 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4926 orntNew[0] = -2; 4927 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4928 orntNew[1] = 0; 4929 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4930 orntNew[2] = 0; 4931 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4932 orntNew[3] = -2; 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 /* E-F face */ 4942 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4943 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4944 orntNew[0] = -2; 4945 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4946 orntNew[1] = -2; 4947 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4948 orntNew[2] = 0; 4949 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4950 orntNew[3] = 0; 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 /* F-G face */ 4960 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4961 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4962 orntNew[0] = -2; 4963 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4964 orntNew[1] = -2; 4965 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 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 /* G-H face */ 4978 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4979 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4980 orntNew[0] = -2; 4981 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4982 orntNew[1] = 0; 4983 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4984 orntNew[2] = 0; 4985 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 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 /* E-H face */ 4996 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4997 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4998 orntNew[0] = -2; 4999 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 5000 orntNew[1] = -2; 5001 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 5002 orntNew[2] = 0; 5003 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5004 orntNew[3] = 0; 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 /* A-E face */ 5014 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 5015 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 5016 orntNew[0] = 0; 5017 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5018 orntNew[1] = 0; 5019 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5020 orntNew[2] = -2; 5021 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 5022 orntNew[3] = -2; 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 /* D-F face */ 5032 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 5033 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 5034 orntNew[0] = -2; 5035 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 5036 orntNew[1] = 0; 5037 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5038 orntNew[2] = 0; 5039 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5040 orntNew[3] = -2; 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 /* C-G face */ 5050 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 5051 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5052 orntNew[0] = -2; 5053 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 5054 orntNew[1] = -2; 5055 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 5056 orntNew[2] = 0; 5057 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5058 orntNew[3] = 0; 5059 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5060 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5061 #if 1 5062 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5063 for (p = 0; p < 4; ++p) { 5064 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); 5065 } 5066 #endif 5067 /* B-H face */ 5068 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 5069 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5070 orntNew[0] = 0; 5071 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5072 orntNew[1] = -2; 5073 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 5074 orntNew[2] = -2; 5075 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 5076 orntNew[3] = 0; 5077 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5078 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5079 #if 1 5080 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5081 for (p = 0; p < 4; ++p) { 5082 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); 5083 } 5084 #endif 5085 for (r = 0; r < 12; ++r) { 5086 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 5087 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 5088 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 5089 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5090 #if 1 5091 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5092 for (p = 0; p < 2; ++p) { 5093 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); 5094 } 5095 #endif 5096 } 5097 } 5098 /* Hybrid split faces have 4 edges and same cells */ 5099 for (f = fMax; f < fEnd; ++f) { 5100 const PetscInt *cone, *ornt, *support; 5101 PetscInt coneNew[4], orntNew[4]; 5102 PetscInt supportNew[2], size, s, c; 5103 5104 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5105 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5106 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5107 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5108 for (r = 0; r < 2; ++r) { 5109 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 5110 5111 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 5112 orntNew[0] = ornt[0]; 5113 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 5114 orntNew[1] = ornt[1]; 5115 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 5116 orntNew[2+r] = 0; 5117 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5118 orntNew[3-r] = 0; 5119 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5120 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5121 #if 1 5122 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 5123 for (p = 0; p < 2; ++p) { 5124 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); 5125 } 5126 for (p = 2; p < 4; ++p) { 5127 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); 5128 } 5129 #endif 5130 for (s = 0; s < size; ++s) { 5131 const PetscInt *coneCell, *orntCell, *fornt; 5132 PetscInt o, of; 5133 5134 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5135 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5136 o = orntCell[0] < 0 ? -1 : 1; 5137 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 5138 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 5139 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 5140 of = fornt[c-2] < 0 ? -1 : 1; 5141 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 5142 } 5143 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5144 #if 1 5145 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 5146 for (p = 0; p < size; ++p) { 5147 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); 5148 } 5149 #endif 5150 } 5151 } 5152 /* Hybrid cell faces have 4 edges and 2 cells */ 5153 for (c = cMax; c < cEnd; ++c) { 5154 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 5155 const PetscInt *cone, *ornt; 5156 PetscInt coneNew[4], orntNew[4]; 5157 PetscInt supportNew[2]; 5158 5159 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5160 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5161 for (r = 0; r < 4; ++r) { 5162 #if 0 5163 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 5164 orntNew[0] = 0; 5165 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 5166 orntNew[1] = 0; 5167 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 5168 orntNew[2] = 0; 5169 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5170 orntNew[3] = 0; 5171 #else 5172 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 5173 orntNew[0] = 0; 5174 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 5175 orntNew[1] = 0; 5176 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 5177 orntNew[2] = 0; 5178 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5179 orntNew[3] = 0; 5180 #endif 5181 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 5182 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 5183 #if 1 5184 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); 5185 for (p = 0; p < 2; ++p) { 5186 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); 5187 } 5188 for (p = 2; p < 4; ++p) { 5189 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); 5190 } 5191 #endif 5192 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 5193 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 5194 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 5195 #if 1 5196 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); 5197 for (p = 0; p < 2; ++p) { 5198 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); 5199 } 5200 #endif 5201 } 5202 } 5203 /* Interior split edges have 2 vertices and the same faces as the parent */ 5204 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5205 for (e = eStart; e < eMax; ++e) { 5206 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5207 5208 for (r = 0; r < 2; ++r) { 5209 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5210 const PetscInt *cone, *ornt, *support; 5211 PetscInt coneNew[2], coneSize, c, supportSize, s; 5212 5213 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5214 coneNew[0] = vStartNew + (cone[0] - vStart); 5215 coneNew[1] = vStartNew + (cone[1] - vStart); 5216 coneNew[(r+1)%2] = newv; 5217 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5218 #if 1 5219 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5220 for (p = 0; p < 2; ++p) { 5221 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); 5222 } 5223 #endif 5224 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5225 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5226 for (s = 0; s < supportSize; ++s) { 5227 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5228 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5229 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5230 for (c = 0; c < coneSize; ++c) { 5231 if (cone[c] == e) break; 5232 } 5233 if (support[s] < fMax) { 5234 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 5235 } else { 5236 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 5237 } 5238 } 5239 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5240 #if 1 5241 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5242 for (p = 0; p < supportSize; ++p) { 5243 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); 5244 } 5245 #endif 5246 } 5247 } 5248 /* Interior face edges have 2 vertices and 2+cells faces */ 5249 for (f = fStart; f < fMax; ++f) { 5250 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}; 5251 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5252 const PetscInt *cone, *coneCell, *orntCell, *support; 5253 PetscInt coneNew[2], coneSize, c, supportSize, s; 5254 5255 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5256 for (r = 0; r < 4; ++r) { 5257 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5258 5259 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5260 coneNew[1] = newv; 5261 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5262 #if 1 5263 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5264 for (p = 0; p < 2; ++p) { 5265 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); 5266 } 5267 #endif 5268 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5269 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5270 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5271 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5272 for (s = 0; s < supportSize; ++s) { 5273 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5274 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5275 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5276 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5277 if (support[s] < cMax) { 5278 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5279 } else { 5280 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 5281 } 5282 } 5283 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5284 #if 1 5285 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5286 for (p = 0; p < 2+supportSize; ++p) { 5287 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); 5288 } 5289 #endif 5290 } 5291 } 5292 /* Interior cell edges have 2 vertices and 4 faces */ 5293 for (c = cStart; c < cMax; ++c) { 5294 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}; 5295 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5296 const PetscInt *cone; 5297 PetscInt coneNew[2], supportNew[4]; 5298 5299 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5300 for (r = 0; r < 6; ++r) { 5301 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5302 5303 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5304 coneNew[1] = newv; 5305 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5306 #if 1 5307 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5308 for (p = 0; p < 2; ++p) { 5309 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); 5310 } 5311 #endif 5312 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5313 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5314 #if 1 5315 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5316 for (p = 0; p < 4; ++p) { 5317 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); 5318 } 5319 #endif 5320 } 5321 } 5322 /* Hybrid edges have two vertices and the same faces */ 5323 for (e = eMax; e < eEnd; ++e) { 5324 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5325 const PetscInt *cone, *support, *fcone; 5326 PetscInt coneNew[2], size, fsize, s; 5327 5328 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5329 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5330 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5331 coneNew[0] = vStartNew + (cone[0] - vStart); 5332 coneNew[1] = vStartNew + (cone[1] - vStart); 5333 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5334 #if 1 5335 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5336 for (p = 0; p < 2; ++p) { 5337 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); 5338 } 5339 #endif 5340 for (s = 0; s < size; ++s) { 5341 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5342 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5343 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5344 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5345 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + 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 < 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 face edges have 2 vertices and 2+cells faces */ 5356 for (f = fMax; f < fEnd; ++f) { 5357 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5358 const PetscInt *cone, *support, *ccone, *cornt; 5359 PetscInt coneNew[2], size, csize, s; 5360 5361 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5362 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5363 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5364 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5365 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 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 + (f - fMax)*2 + 0; 5374 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5375 for (s = 0; s < size; ++s) { 5376 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5377 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5378 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5379 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5380 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]); 5381 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 5382 } 5383 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5384 #if 1 5385 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5386 for (p = 0; p < 2+size; ++p) { 5387 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); 5388 } 5389 #endif 5390 } 5391 /* Hybrid cell edges have 2 vertices and 4 faces */ 5392 for (c = cMax; c < cEnd; ++c) { 5393 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5394 const PetscInt *cone, *support; 5395 PetscInt coneNew[2], size; 5396 5397 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5398 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5399 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5400 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5401 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5402 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5403 #if 1 5404 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5405 for (p = 0; p < 2; ++p) { 5406 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); 5407 } 5408 #endif 5409 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5410 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5411 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5412 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5413 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5414 #if 1 5415 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5416 for (p = 0; p < 4; ++p) { 5417 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); 5418 } 5419 #endif 5420 } 5421 /* Interior vertices have identical supports */ 5422 for (v = vStart; v < vEnd; ++v) { 5423 const PetscInt newp = vStartNew + (v - vStart); 5424 const PetscInt *support, *cone; 5425 PetscInt size, s; 5426 5427 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5428 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5429 for (s = 0; s < size; ++s) { 5430 PetscInt r = 0; 5431 5432 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5433 if (cone[1] == v) r = 1; 5434 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5435 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5436 } 5437 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5438 #if 1 5439 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5440 for (p = 0; p < size; ++p) { 5441 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); 5442 } 5443 #endif 5444 } 5445 /* Interior edge vertices have 2 + faces supports */ 5446 for (e = eStart; e < eMax; ++e) { 5447 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5448 const PetscInt *cone, *support; 5449 PetscInt size, s; 5450 5451 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5452 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5453 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5454 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5455 for (s = 0; s < size; ++s) { 5456 PetscInt r; 5457 5458 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5459 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5460 if (support[s] < fMax) { 5461 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5462 } else { 5463 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5464 } 5465 } 5466 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5467 #if 1 5468 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5469 for (p = 0; p < 2+size; ++p) { 5470 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); 5471 } 5472 #endif 5473 } 5474 /* Interior face vertices have 4 + cells supports */ 5475 for (f = fStart; f < fMax; ++f) { 5476 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5477 const PetscInt *cone, *support; 5478 PetscInt size, s; 5479 5480 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5481 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5482 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5483 for (s = 0; s < size; ++s) { 5484 PetscInt r; 5485 5486 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5487 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5488 if (support[s] < cMax) { 5489 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5490 } else { 5491 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5492 } 5493 } 5494 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5495 #if 1 5496 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5497 for (p = 0; p < 4+size; ++p) { 5498 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); 5499 } 5500 #endif 5501 } 5502 /* Cell vertices have 6 supports */ 5503 for (c = cStart; c < cMax; ++c) { 5504 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5505 PetscInt supportNew[6]; 5506 5507 for (r = 0; r < 6; ++r) { 5508 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5509 } 5510 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5511 } 5512 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5513 break; 5514 default: 5515 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5516 } 5517 PetscFunctionReturn(0); 5518 } 5519 5520 #undef __FUNCT__ 5521 #define __FUNCT__ "CellRefinerSetCoordinates" 5522 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5523 { 5524 PetscSection coordSection, coordSectionNew; 5525 Vec coordinates, coordinatesNew; 5526 PetscScalar *coords, *coordsNew; 5527 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5528 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5529 PetscErrorCode ierr; 5530 5531 PetscFunctionBegin; 5532 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 5533 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5534 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5535 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5536 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5537 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5538 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5539 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5540 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5541 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5542 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 5543 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5544 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5545 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 5546 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5547 if (cMax < 0) cMax = cEnd; 5548 if (fMax < 0) fMax = fEnd; 5549 if (eMax < 0) eMax = eEnd; 5550 /* All vertices have the spaceDim coordinates */ 5551 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5552 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 5553 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 5554 } 5555 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5556 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 5557 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5558 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5559 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 5560 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5561 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5562 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 5563 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 5564 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 5565 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5566 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5567 switch (refiner) { 5568 case REFINER_NOOP: break; 5569 case REFINER_HEX_3D: 5570 case REFINER_HYBRID_HEX_3D: 5571 /* Face vertices have the average of corner coordinates */ 5572 for (f = fStart; f < fMax; ++f) { 5573 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5574 PetscInt *cone = NULL; 5575 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5576 5577 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5578 for (p = 0; p < closureSize*2; p += 2) { 5579 const PetscInt point = cone[p]; 5580 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5581 } 5582 for (v = 0; v < coneSize; ++v) { 5583 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5584 } 5585 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5586 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5587 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5588 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5589 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5590 } 5591 case REFINER_HEX_2D: 5592 case REFINER_HYBRID_HEX_2D: 5593 case REFINER_SIMPLEX_1D: 5594 /* Cell vertices have the average of corner coordinates */ 5595 for (c = cStart; c < cMax; ++c) { 5596 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 5597 PetscInt *cone = NULL; 5598 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5599 5600 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5601 for (p = 0; p < closureSize*2; p += 2) { 5602 const PetscInt point = cone[p]; 5603 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5604 } 5605 for (v = 0; v < coneSize; ++v) { 5606 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5607 } 5608 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5609 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5610 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5611 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5612 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5613 } 5614 case REFINER_SIMPLEX_2D: 5615 case REFINER_HYBRID_SIMPLEX_2D: 5616 case REFINER_SIMPLEX_3D: 5617 case REFINER_HYBRID_SIMPLEX_3D: 5618 /* Edge vertices have the average of endpoint coordinates */ 5619 for (e = eStart; e < eMax; ++e) { 5620 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5621 const PetscInt *cone; 5622 PetscInt coneSize, offA, offB, offnew, d; 5623 5624 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5625 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5626 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5627 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5628 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5629 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5630 ierr = DMPlexLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 5631 for (d = 0; d < spaceDim; ++d) { 5632 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 5633 } 5634 } 5635 /* Old vertices have the same coordinates */ 5636 for (v = vStart; v < vEnd; ++v) { 5637 const PetscInt newv = vStartNew + (v - vStart); 5638 PetscInt off, offnew, d; 5639 5640 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5641 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5642 for (d = 0; d < spaceDim; ++d) { 5643 coordsNew[offnew+d] = coords[off+d]; 5644 } 5645 } 5646 break; 5647 default: 5648 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5649 } 5650 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5651 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5652 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5653 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5654 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5655 if (dm->maxCell) { 5656 const PetscReal *maxCell, *L; 5657 const DMBoundaryType *bd; 5658 ierr = DMGetPeriodicity(dm, &maxCell, &L, &bd);CHKERRQ(ierr); 5659 ierr = DMSetPeriodicity(rdm, maxCell, L, bd);CHKERRQ(ierr); 5660 } 5661 PetscFunctionReturn(0); 5662 } 5663 5664 #undef __FUNCT__ 5665 #define __FUNCT__ "DMPlexCreateProcessSF" 5666 /*@ 5667 DMPlexCreateProcessSF - Create an SF which just has process connectivity 5668 5669 Collective on DM 5670 5671 Input Parameters: 5672 + dm - The DM 5673 - sfPoint - The PetscSF which encodes point connectivity 5674 5675 Output Parameters: 5676 + processRanks - A list of process neighbors, or NULL 5677 - sfProcess - An SF encoding the process connectivity, or NULL 5678 5679 Level: developer 5680 5681 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 5682 @*/ 5683 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5684 { 5685 PetscInt numRoots, numLeaves, l; 5686 const PetscInt *localPoints; 5687 const PetscSFNode *remotePoints; 5688 PetscInt *localPointsNew; 5689 PetscSFNode *remotePointsNew; 5690 PetscInt *ranks, *ranksNew; 5691 PetscMPIInt numProcs; 5692 PetscErrorCode ierr; 5693 5694 PetscFunctionBegin; 5695 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5696 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 5697 if (processRanks) {PetscValidPointer(processRanks, 3);} 5698 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 5699 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &numProcs);CHKERRQ(ierr); 5700 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5701 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5702 for (l = 0; l < numLeaves; ++l) { 5703 ranks[l] = remotePoints[l].rank; 5704 } 5705 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5706 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5707 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5708 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5709 for (l = 0; l < numLeaves; ++l) { 5710 ranksNew[l] = ranks[l]; 5711 localPointsNew[l] = l; 5712 remotePointsNew[l].index = 0; 5713 remotePointsNew[l].rank = ranksNew[l]; 5714 } 5715 ierr = PetscFree(ranks);CHKERRQ(ierr); 5716 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 5717 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 5718 if (sfProcess) { 5719 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5720 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 5721 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5722 ierr = PetscSFSetGraph(*sfProcess, numProcs, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5723 } 5724 PetscFunctionReturn(0); 5725 } 5726 5727 #undef __FUNCT__ 5728 #define __FUNCT__ "CellRefinerCreateSF" 5729 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5730 { 5731 PetscSF sf, sfNew, sfProcess; 5732 IS processRanks; 5733 MPI_Datatype depthType; 5734 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5735 const PetscInt *localPoints, *neighbors; 5736 const PetscSFNode *remotePoints; 5737 PetscInt *localPointsNew; 5738 PetscSFNode *remotePointsNew; 5739 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5740 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5741 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5742 PetscErrorCode ierr; 5743 5744 PetscFunctionBegin; 5745 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5746 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5747 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5748 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5749 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5750 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5751 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5752 cMax = cMax < 0 ? cEnd : cMax; 5753 fMax = fMax < 0 ? fEnd : fMax; 5754 eMax = eMax < 0 ? eEnd : eMax; 5755 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5756 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5757 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5758 /* Calculate size of new SF */ 5759 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5760 if (numRoots < 0) PetscFunctionReturn(0); 5761 for (l = 0; l < numLeaves; ++l) { 5762 const PetscInt p = localPoints[l]; 5763 5764 switch (refiner) { 5765 case REFINER_SIMPLEX_1D: 5766 if ((p >= vStart) && (p < vEnd)) { 5767 /* Interior vertices stay the same */ 5768 ++numLeavesNew; 5769 } else if ((p >= cStart && p < cMax)) { 5770 /* Interior cells add new cells and interior vertices */ 5771 numLeavesNew += 2 + 1; 5772 } 5773 break; 5774 case REFINER_SIMPLEX_2D: 5775 case REFINER_HYBRID_SIMPLEX_2D: 5776 if ((p >= vStart) && (p < vEnd)) { 5777 /* Interior vertices stay the same */ 5778 ++numLeavesNew; 5779 } else if ((p >= fStart) && (p < fMax)) { 5780 /* Interior faces add new faces and vertex */ 5781 numLeavesNew += 2 + 1; 5782 } else if ((p >= fMax) && (p < fEnd)) { 5783 /* Hybrid faces stay the same */ 5784 ++numLeavesNew; 5785 } else if ((p >= cStart) && (p < cMax)) { 5786 /* Interior cells add new cells and interior faces */ 5787 numLeavesNew += 4 + 3; 5788 } else if ((p >= cMax) && (p < cEnd)) { 5789 /* Hybrid cells add new cells and hybrid face */ 5790 numLeavesNew += 2 + 1; 5791 } 5792 break; 5793 case REFINER_HEX_2D: 5794 case REFINER_HYBRID_HEX_2D: 5795 if ((p >= vStart) && (p < vEnd)) { 5796 /* Interior vertices stay the same */ 5797 ++numLeavesNew; 5798 } else if ((p >= fStart) && (p < fMax)) { 5799 /* Interior faces add new faces and vertex */ 5800 numLeavesNew += 2 + 1; 5801 } else if ((p >= fMax) && (p < fEnd)) { 5802 /* Hybrid faces stay the same */ 5803 ++numLeavesNew; 5804 } else if ((p >= cStart) && (p < cMax)) { 5805 /* Interior cells add new cells, interior faces, and vertex */ 5806 numLeavesNew += 4 + 4 + 1; 5807 } else if ((p >= cMax) && (p < cEnd)) { 5808 /* Hybrid cells add new cells and hybrid face */ 5809 numLeavesNew += 2 + 1; 5810 } 5811 break; 5812 case REFINER_SIMPLEX_3D: 5813 case REFINER_HYBRID_SIMPLEX_3D: 5814 if ((p >= vStart) && (p < vEnd)) { 5815 /* Interior vertices stay the same */ 5816 ++numLeavesNew; 5817 } else if ((p >= eStart) && (p < eMax)) { 5818 /* Interior edges add new edges and vertex */ 5819 numLeavesNew += 2 + 1; 5820 } else if ((p >= eMax) && (p < eEnd)) { 5821 /* Hybrid edges stay the same */ 5822 ++numLeavesNew; 5823 } else if ((p >= fStart) && (p < fMax)) { 5824 /* Interior faces add new faces and edges */ 5825 numLeavesNew += 4 + 3; 5826 } else if ((p >= fMax) && (p < fEnd)) { 5827 /* Hybrid faces add new faces and edges */ 5828 numLeavesNew += 2 + 1; 5829 } else if ((p >= cStart) && (p < cMax)) { 5830 /* Interior cells add new cells, faces, and edges */ 5831 numLeavesNew += 8 + 8 + 1; 5832 } else if ((p >= cMax) && (p < cEnd)) { 5833 /* Hybrid cells add new cells and faces */ 5834 numLeavesNew += 4 + 3; 5835 } 5836 break; 5837 case REFINER_HEX_3D: 5838 case REFINER_HYBRID_HEX_3D: 5839 if ((p >= vStart) && (p < vEnd)) { 5840 /* Old vertices stay the same */ 5841 ++numLeavesNew; 5842 } else if ((p >= eStart) && (p < eMax)) { 5843 /* Interior edges add new edges, and vertex */ 5844 numLeavesNew += 2 + 1; 5845 } else if ((p >= eMax) && (p < eEnd)) { 5846 /* Hybrid edges stay the same */ 5847 ++numLeavesNew; 5848 } else if ((p >= fStart) && (p < fMax)) { 5849 /* Interior faces add new faces, edges, and vertex */ 5850 numLeavesNew += 4 + 4 + 1; 5851 } else if ((p >= fMax) && (p < fEnd)) { 5852 /* Hybrid faces add new faces and edges */ 5853 numLeavesNew += 2 + 1; 5854 } else if ((p >= cStart) && (p < cMax)) { 5855 /* Interior cells add new cells, faces, edges, and vertex */ 5856 numLeavesNew += 8 + 12 + 6 + 1; 5857 } else if ((p >= cStart) && (p < cEnd)) { 5858 /* Hybrid cells add new cells, faces, and edges */ 5859 numLeavesNew += 4 + 4 + 1; 5860 } 5861 break; 5862 default: 5863 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5864 } 5865 } 5866 /* Communicate depthSizes for each remote rank */ 5867 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5868 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5869 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5870 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5871 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5872 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5873 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5874 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5875 for (n = 0; n < numNeighbors; ++n) { 5876 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5877 } 5878 depthSizeOld[depth] = cMax; 5879 depthSizeOld[0] = vMax; 5880 depthSizeOld[depth-1] = fMax; 5881 depthSizeOld[1] = eMax; 5882 5883 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5884 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5885 5886 depthSizeOld[depth] = cEnd - cStart; 5887 depthSizeOld[0] = vEnd - vStart; 5888 depthSizeOld[depth-1] = fEnd - fStart; 5889 depthSizeOld[1] = eEnd - eStart; 5890 5891 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5892 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5893 for (n = 0; n < numNeighbors; ++n) { 5894 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5895 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 5896 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]; 5897 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 5898 } 5899 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5900 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5901 /* Calculate new point SF */ 5902 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5903 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5904 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5905 for (l = 0, m = 0; l < numLeaves; ++l) { 5906 PetscInt p = localPoints[l]; 5907 PetscInt rp = remotePoints[l].index, n; 5908 PetscMPIInt rrank = remotePoints[l].rank; 5909 5910 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5911 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5912 switch (refiner) { 5913 case REFINER_SIMPLEX_1D: 5914 if ((p >= vStart) && (p < vEnd)) { 5915 /* Old vertices stay the same */ 5916 localPointsNew[m] = vStartNew + (p - vStart); 5917 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5918 remotePointsNew[m].rank = rrank; 5919 ++m; 5920 } else if ((p >= cStart) && (p < cMax)) { 5921 /* Old interior cells add new cells and vertex */ 5922 for (r = 0; r < 2; ++r, ++m) { 5923 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 5924 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 5925 remotePointsNew[m].rank = rrank; 5926 } 5927 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 5928 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 5929 remotePointsNew[m].rank = rrank; 5930 ++m; 5931 } 5932 break; 5933 case REFINER_SIMPLEX_2D: 5934 case REFINER_HYBRID_SIMPLEX_2D: 5935 if ((p >= vStart) && (p < vEnd)) { 5936 /* Old vertices stay the same */ 5937 localPointsNew[m] = vStartNew + (p - vStart); 5938 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5939 remotePointsNew[m].rank = rrank; 5940 ++m; 5941 } else if ((p >= fStart) && (p < fMax)) { 5942 /* Old interior faces add new faces and vertex */ 5943 for (r = 0; r < 2; ++r, ++m) { 5944 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5945 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5946 remotePointsNew[m].rank = rrank; 5947 } 5948 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5949 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5950 remotePointsNew[m].rank = rrank; 5951 ++m; 5952 } else if ((p >= fMax) && (p < fEnd)) { 5953 /* Old hybrid faces stay the same */ 5954 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5955 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5956 remotePointsNew[m].rank = rrank; 5957 ++m; 5958 } else if ((p >= cStart) && (p < cMax)) { 5959 /* Old interior cells add new cells and interior faces */ 5960 for (r = 0; r < 4; ++r, ++m) { 5961 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5962 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5963 remotePointsNew[m].rank = rrank; 5964 } 5965 for (r = 0; r < 3; ++r, ++m) { 5966 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5967 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5968 remotePointsNew[m].rank = rrank; 5969 } 5970 } else if ((p >= cMax) && (p < cEnd)) { 5971 /* Old hybrid cells add new cells and hybrid face */ 5972 for (r = 0; r < 2; ++r, ++m) { 5973 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5974 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5975 remotePointsNew[m].rank = rrank; 5976 } 5977 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5978 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]); 5979 remotePointsNew[m].rank = rrank; 5980 ++m; 5981 } 5982 break; 5983 case REFINER_HEX_2D: 5984 case REFINER_HYBRID_HEX_2D: 5985 if ((p >= vStart) && (p < vEnd)) { 5986 /* Old vertices stay the same */ 5987 localPointsNew[m] = vStartNew + (p - vStart); 5988 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5989 remotePointsNew[m].rank = rrank; 5990 ++m; 5991 } else if ((p >= fStart) && (p < fMax)) { 5992 /* Old interior faces add new faces and vertex */ 5993 for (r = 0; r < 2; ++r, ++m) { 5994 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5995 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5996 remotePointsNew[m].rank = rrank; 5997 } 5998 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5999 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 6000 remotePointsNew[m].rank = rrank; 6001 ++m; 6002 } else if ((p >= fMax) && (p < fEnd)) { 6003 /* Old hybrid faces stay the same */ 6004 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 6005 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 6006 remotePointsNew[m].rank = rrank; 6007 ++m; 6008 } else if ((p >= cStart) && (p < cMax)) { 6009 /* Old interior cells add new cells, interior faces, and vertex */ 6010 for (r = 0; r < 4; ++r, ++m) { 6011 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 6012 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 6013 remotePointsNew[m].rank = rrank; 6014 } 6015 for (r = 0; r < 4; ++r, ++m) { 6016 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 6017 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 6018 remotePointsNew[m].rank = rrank; 6019 } 6020 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 6021 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 6022 remotePointsNew[m].rank = rrank; 6023 ++m; 6024 } else if ((p >= cStart) && (p < cMax)) { 6025 /* Old hybrid cells add new cells and hybrid face */ 6026 for (r = 0; r < 2; ++r, ++m) { 6027 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 6028 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 6029 remotePointsNew[m].rank = rrank; 6030 } 6031 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6032 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]); 6033 remotePointsNew[m].rank = rrank; 6034 ++m; 6035 } 6036 break; 6037 case REFINER_SIMPLEX_3D: 6038 case REFINER_HYBRID_SIMPLEX_3D: 6039 if ((p >= vStart) && (p < vEnd)) { 6040 /* Interior vertices stay the same */ 6041 localPointsNew[m] = vStartNew + (p - vStart); 6042 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6043 remotePointsNew[m].rank = rrank; 6044 ++m; 6045 } else if ((p >= eStart) && (p < eMax)) { 6046 /* Interior edges add new edges and vertex */ 6047 for (r = 0; r < 2; ++r, ++m) { 6048 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6049 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6050 remotePointsNew[m].rank = rrank; 6051 } 6052 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6053 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6054 remotePointsNew[m].rank = rrank; 6055 ++m; 6056 } else if ((p >= eMax) && (p < eEnd)) { 6057 /* Hybrid edges stay the same */ 6058 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6059 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]); 6060 remotePointsNew[m].rank = rrank; 6061 ++m; 6062 } else if ((p >= fStart) && (p < fMax)) { 6063 /* Interior faces add new faces and edges */ 6064 for (r = 0; r < 4; ++r, ++m) { 6065 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6066 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6067 remotePointsNew[m].rank = rrank; 6068 } 6069 for (r = 0; r < 3; ++r, ++m) { 6070 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6071 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 6072 remotePointsNew[m].rank = rrank; 6073 } 6074 } else if ((p >= fMax) && (p < fEnd)) { 6075 /* Hybrid faces add new faces and edges */ 6076 for (r = 0; r < 2; ++r, ++m) { 6077 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6078 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; 6079 remotePointsNew[m].rank = rrank; 6080 } 6081 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 6082 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]); 6083 remotePointsNew[m].rank = rrank; 6084 ++m; 6085 } else if ((p >= cStart) && (p < cMax)) { 6086 /* Interior cells add new cells, faces, and edges */ 6087 for (r = 0; r < 8; ++r, ++m) { 6088 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6089 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6090 remotePointsNew[m].rank = rrank; 6091 } 6092 for (r = 0; r < 8; ++r, ++m) { 6093 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6094 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 6095 remotePointsNew[m].rank = rrank; 6096 } 6097 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 6098 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; 6099 remotePointsNew[m].rank = rrank; 6100 ++m; 6101 } else if ((p >= cMax) && (p < cEnd)) { 6102 /* Hybrid cells add new cells and faces */ 6103 for (r = 0; r < 4; ++r, ++m) { 6104 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6105 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6106 remotePointsNew[m].rank = rrank; 6107 } 6108 for (r = 0; r < 3; ++r, ++m) { 6109 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6110 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; 6111 remotePointsNew[m].rank = rrank; 6112 } 6113 } 6114 break; 6115 case REFINER_HEX_3D: 6116 case REFINER_HYBRID_HEX_3D: 6117 if ((p >= vStart) && (p < vEnd)) { 6118 /* Interior vertices stay the same */ 6119 localPointsNew[m] = vStartNew + (p - vStart); 6120 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 6121 remotePointsNew[m].rank = rrank; 6122 ++m; 6123 } else if ((p >= eStart) && (p < eMax)) { 6124 /* Interior edges add new edges and vertex */ 6125 for (r = 0; r < 2; ++r, ++m) { 6126 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 6127 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 6128 remotePointsNew[m].rank = rrank; 6129 } 6130 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 6131 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 6132 remotePointsNew[m].rank = rrank; 6133 ++m; 6134 } else if ((p >= eMax) && (p < eEnd)) { 6135 /* Hybrid edges stay the same */ 6136 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6137 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]); 6138 remotePointsNew[m].rank = rrank; 6139 ++m; 6140 } else if ((p >= fStart) && (p < fMax)) { 6141 /* Interior faces add new faces, edges, and vertex */ 6142 for (r = 0; r < 4; ++r, ++m) { 6143 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 6144 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 6145 remotePointsNew[m].rank = rrank; 6146 } 6147 for (r = 0; r < 4; ++r, ++m) { 6148 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6149 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 6150 remotePointsNew[m].rank = rrank; 6151 } 6152 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6153 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 6154 remotePointsNew[m].rank = rrank; 6155 ++m; 6156 } else if ((p >= fMax) && (p < fEnd)) { 6157 /* Hybrid faces add new faces and edges */ 6158 for (r = 0; r < 2; ++r, ++m) { 6159 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6160 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; 6161 remotePointsNew[m].rank = rrank; 6162 } 6163 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 6164 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 6165 remotePointsNew[m].rank = rrank; 6166 ++m; 6167 } else if ((p >= cStart) && (p < cMax)) { 6168 /* Interior cells add new cells, faces, edges, and vertex */ 6169 for (r = 0; r < 8; ++r, ++m) { 6170 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6171 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6172 remotePointsNew[m].rank = rrank; 6173 } 6174 for (r = 0; r < 12; ++r, ++m) { 6175 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6176 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6177 remotePointsNew[m].rank = rrank; 6178 } 6179 for (r = 0; r < 6; ++r, ++m) { 6180 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6181 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; 6182 remotePointsNew[m].rank = rrank; 6183 } 6184 for (r = 0; r < 1; ++r, ++m) { 6185 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6186 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6187 remotePointsNew[m].rank = rrank; 6188 } 6189 } else if ((p >= cMax) && (p < cEnd)) { 6190 /* Hybrid cells add new cells, faces, and edges */ 6191 for (r = 0; r < 4; ++r, ++m) { 6192 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6193 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6194 remotePointsNew[m].rank = rrank; 6195 } 6196 for (r = 0; r < 4; ++r, ++m) { 6197 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6198 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; 6199 remotePointsNew[m].rank = rrank; 6200 } 6201 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 6202 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]); 6203 remotePointsNew[m].rank = rrank; 6204 ++m; 6205 } 6206 break; 6207 default: 6208 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6209 } 6210 } 6211 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6212 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6213 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6214 { 6215 PetscSFNode *rp, *rtmp; 6216 PetscInt *lp, *idx, *ltmp, i; 6217 6218 /* SF needs sorted leaves to correct calculate Gather */ 6219 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 6220 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 6221 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 6222 for (i = 0; i < numLeavesNew; ++i) { 6223 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); 6224 idx[i] = i; 6225 } 6226 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 6227 for (i = 0; i < numLeavesNew; ++i) { 6228 lp[i] = localPointsNew[idx[i]]; 6229 rp[i] = remotePointsNew[idx[i]]; 6230 } 6231 ltmp = localPointsNew; 6232 localPointsNew = lp; 6233 rtmp = remotePointsNew; 6234 remotePointsNew = rp; 6235 ierr = PetscFree(idx);CHKERRQ(ierr); 6236 ierr = PetscFree(ltmp);CHKERRQ(ierr); 6237 ierr = PetscFree(rtmp);CHKERRQ(ierr); 6238 } 6239 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6240 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6241 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6242 PetscFunctionReturn(0); 6243 } 6244 6245 #undef __FUNCT__ 6246 #define __FUNCT__ "CellRefinerCreateLabels" 6247 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6248 { 6249 PetscInt numLabels, l; 6250 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6251 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6252 PetscErrorCode ierr; 6253 6254 PetscFunctionBegin; 6255 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6256 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6257 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6258 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6259 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6260 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6261 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6262 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6263 switch (refiner) { 6264 case REFINER_NOOP: 6265 case REFINER_SIMPLEX_1D: 6266 case REFINER_SIMPLEX_2D: 6267 case REFINER_HEX_2D: 6268 case REFINER_SIMPLEX_3D: 6269 case REFINER_HEX_3D: 6270 break; 6271 case REFINER_HYBRID_SIMPLEX_3D: 6272 case REFINER_HYBRID_HEX_3D: 6273 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6274 case REFINER_HYBRID_SIMPLEX_2D: 6275 case REFINER_HYBRID_HEX_2D: 6276 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6277 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6278 break; 6279 default: 6280 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6281 } 6282 for (l = 0; l < numLabels; ++l) { 6283 DMLabel label, labelNew; 6284 const char *lname; 6285 PetscBool isDepth; 6286 IS valueIS; 6287 const PetscInt *values; 6288 PetscInt numValues, val; 6289 6290 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6291 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6292 if (isDepth) continue; 6293 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6294 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6295 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6296 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6297 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6298 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6299 for (val = 0; val < numValues; ++val) { 6300 IS pointIS; 6301 const PetscInt *points; 6302 PetscInt numPoints, n; 6303 6304 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6305 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6306 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6307 /* Ensure refined label is created with same number of strata as 6308 * original (even if no entries here). */ 6309 if (!numPoints) { 6310 ierr = DMLabelSetValue(labelNew, 0, values[val]);CHKERRQ(ierr); 6311 ierr = DMLabelClearValue(labelNew, 0, values[val]);CHKERRQ(ierr); 6312 } 6313 for (n = 0; n < numPoints; ++n) { 6314 const PetscInt p = points[n]; 6315 switch (refiner) { 6316 case REFINER_SIMPLEX_1D: 6317 if ((p >= vStart) && (p < vEnd)) { 6318 /* Old vertices stay the same */ 6319 newp = vStartNew + (p - vStart); 6320 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6321 } else if ((p >= cStart) && (p < cEnd)) { 6322 /* Old cells add new cells and vertex */ 6323 newp = vStartNew + (vEnd - vStart) + (p - cStart); 6324 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6325 for (r = 0; r < 2; ++r) { 6326 newp = cStartNew + (p - cStart)*2 + r; 6327 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6328 } 6329 } 6330 break; 6331 case REFINER_SIMPLEX_2D: 6332 if ((p >= vStart) && (p < vEnd)) { 6333 /* Old vertices stay the same */ 6334 newp = vStartNew + (p - vStart); 6335 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6336 } else if ((p >= fStart) && (p < fEnd)) { 6337 /* Old faces add new faces and vertex */ 6338 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6339 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6340 for (r = 0; r < 2; ++r) { 6341 newp = fStartNew + (p - fStart)*2 + r; 6342 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6343 } 6344 } else if ((p >= cStart) && (p < cEnd)) { 6345 /* Old cells add new cells and interior faces */ 6346 for (r = 0; r < 4; ++r) { 6347 newp = cStartNew + (p - cStart)*4 + r; 6348 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6349 } 6350 for (r = 0; r < 3; ++r) { 6351 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6352 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6353 } 6354 } 6355 break; 6356 case REFINER_HEX_2D: 6357 if ((p >= vStart) && (p < vEnd)) { 6358 /* Old vertices stay the same */ 6359 newp = vStartNew + (p - vStart); 6360 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6361 } else if ((p >= fStart) && (p < fEnd)) { 6362 /* Old faces add new faces and vertex */ 6363 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6364 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6365 for (r = 0; r < 2; ++r) { 6366 newp = fStartNew + (p - fStart)*2 + r; 6367 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6368 } 6369 } else if ((p >= cStart) && (p < cEnd)) { 6370 /* Old cells add new cells and interior faces and vertex */ 6371 for (r = 0; r < 4; ++r) { 6372 newp = cStartNew + (p - cStart)*4 + r; 6373 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6374 } 6375 for (r = 0; r < 4; ++r) { 6376 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6377 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6378 } 6379 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6380 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6381 } 6382 break; 6383 case REFINER_HYBRID_SIMPLEX_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 and interior faces */ 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 < 3; ++r) { 6407 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6408 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6409 } 6410 } else if ((p >= cMax) && (p < cEnd)) { 6411 /* Old hybrid cells add new cells and hybrid face */ 6412 for (r = 0; r < 2; ++r) { 6413 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6414 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6415 } 6416 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6417 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6418 } 6419 break; 6420 case REFINER_HYBRID_HEX_2D: 6421 if ((p >= vStart) && (p < vEnd)) { 6422 /* Old vertices stay the same */ 6423 newp = vStartNew + (p - vStart); 6424 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6425 } else if ((p >= fStart) && (p < fMax)) { 6426 /* Old interior faces add new faces and vertex */ 6427 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6428 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6429 for (r = 0; r < 2; ++r) { 6430 newp = fStartNew + (p - fStart)*2 + r; 6431 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6432 } 6433 } else if ((p >= fMax) && (p < fEnd)) { 6434 /* Old hybrid faces stay the same */ 6435 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6436 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6437 } else if ((p >= cStart) && (p < cMax)) { 6438 /* Old interior cells add new cells, interior faces, and vertex */ 6439 for (r = 0; r < 4; ++r) { 6440 newp = cStartNew + (p - cStart)*4 + r; 6441 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6442 } 6443 for (r = 0; r < 4; ++r) { 6444 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6445 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6446 } 6447 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6448 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6449 } else if ((p >= cMax) && (p < cEnd)) { 6450 /* Old hybrid cells add new cells and hybrid face */ 6451 for (r = 0; r < 2; ++r) { 6452 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6453 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6454 } 6455 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6456 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6457 } 6458 break; 6459 case REFINER_SIMPLEX_3D: 6460 if ((p >= vStart) && (p < vEnd)) { 6461 /* Old vertices stay the same */ 6462 newp = vStartNew + (p - vStart); 6463 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6464 } else if ((p >= eStart) && (p < eEnd)) { 6465 /* Old edges add new edges and vertex */ 6466 for (r = 0; r < 2; ++r) { 6467 newp = eStartNew + (p - eStart)*2 + r; 6468 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6469 } 6470 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6471 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6472 } else if ((p >= fStart) && (p < fEnd)) { 6473 /* Old faces add new faces and edges */ 6474 for (r = 0; r < 4; ++r) { 6475 newp = fStartNew + (p - fStart)*4 + r; 6476 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6477 } 6478 for (r = 0; r < 3; ++r) { 6479 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6480 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6481 } 6482 } else if ((p >= cStart) && (p < cEnd)) { 6483 /* Old cells add new cells and interior faces and edges */ 6484 for (r = 0; r < 8; ++r) { 6485 newp = cStartNew + (p - cStart)*8 + r; 6486 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6487 } 6488 for (r = 0; r < 8; ++r) { 6489 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6490 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6491 } 6492 for (r = 0; r < 1; ++r) { 6493 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6494 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6495 } 6496 } 6497 break; 6498 case REFINER_HYBRID_SIMPLEX_3D: 6499 if ((p >= vStart) && (p < vEnd)) { 6500 /* Interior vertices stay the same */ 6501 newp = vStartNew + (p - vStart); 6502 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6503 } else if ((p >= eStart) && (p < eMax)) { 6504 /* Interior edges add new edges and vertex */ 6505 for (r = 0; r < 2; ++r) { 6506 newp = eStartNew + (p - eStart)*2 + r; 6507 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6508 } 6509 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6510 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6511 } else if ((p >= eMax) && (p < eEnd)) { 6512 /* Hybrid edges stay the same */ 6513 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6514 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6515 } else if ((p >= fStart) && (p < fMax)) { 6516 /* Interior faces add new faces and edges */ 6517 for (r = 0; r < 4; ++r) { 6518 newp = fStartNew + (p - fStart)*4 + r; 6519 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6520 } 6521 for (r = 0; r < 3; ++r) { 6522 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6523 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6524 } 6525 } else if ((p >= fMax) && (p < fEnd)) { 6526 /* Hybrid faces add new faces and edges */ 6527 for (r = 0; r < 2; ++r) { 6528 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6529 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6530 } 6531 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6532 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6533 } else if ((p >= cStart) && (p < cMax)) { 6534 /* Interior cells add new cells, faces, and edges */ 6535 for (r = 0; r < 8; ++r) { 6536 newp = cStartNew + (p - cStart)*8 + r; 6537 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6538 } 6539 for (r = 0; r < 8; ++r) { 6540 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6541 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6542 } 6543 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6544 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6545 } else if ((p >= cMax) && (p < cEnd)) { 6546 /* Hybrid cells add new cells and faces */ 6547 for (r = 0; r < 4; ++r) { 6548 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6549 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6550 } 6551 for (r = 0; r < 3; ++r) { 6552 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6553 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6554 } 6555 } 6556 break; 6557 case REFINER_HEX_3D: 6558 if ((p >= vStart) && (p < vEnd)) { 6559 /* Old vertices stay the same */ 6560 newp = vStartNew + (p - vStart); 6561 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6562 } else if ((p >= eStart) && (p < eEnd)) { 6563 /* Old edges add new edges and vertex */ 6564 for (r = 0; r < 2; ++r) { 6565 newp = eStartNew + (p - eStart)*2 + r; 6566 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6567 } 6568 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6569 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6570 } else if ((p >= fStart) && (p < fEnd)) { 6571 /* Old faces add new faces, edges, and vertex */ 6572 for (r = 0; r < 4; ++r) { 6573 newp = fStartNew + (p - fStart)*4 + r; 6574 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6575 } 6576 for (r = 0; r < 4; ++r) { 6577 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6578 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6579 } 6580 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6581 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6582 } else if ((p >= cStart) && (p < cEnd)) { 6583 /* Old cells add new cells, faces, edges, and vertex */ 6584 for (r = 0; r < 8; ++r) { 6585 newp = cStartNew + (p - cStart)*8 + r; 6586 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6587 } 6588 for (r = 0; r < 12; ++r) { 6589 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6590 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6591 } 6592 for (r = 0; r < 6; ++r) { 6593 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6594 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6595 } 6596 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6597 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6598 } 6599 break; 6600 case REFINER_HYBRID_HEX_3D: 6601 if ((p >= vStart) && (p < vEnd)) { 6602 /* Interior vertices stay the same */ 6603 newp = vStartNew + (p - vStart); 6604 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6605 } else if ((p >= eStart) && (p < eMax)) { 6606 /* Interior edges add new edges and vertex */ 6607 for (r = 0; r < 2; ++r) { 6608 newp = eStartNew + (p - eStart)*2 + r; 6609 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6610 } 6611 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6612 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6613 } else if ((p >= eMax) && (p < eEnd)) { 6614 /* Hybrid edges stay the same */ 6615 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6616 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6617 } else if ((p >= fStart) && (p < fMax)) { 6618 /* Interior faces add new faces, edges, and vertex */ 6619 for (r = 0; r < 4; ++r) { 6620 newp = fStartNew + (p - fStart)*4 + r; 6621 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6622 } 6623 for (r = 0; r < 4; ++r) { 6624 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6625 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6626 } 6627 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6628 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6629 } else if ((p >= fMax) && (p < fEnd)) { 6630 /* Hybrid faces add new faces and edges */ 6631 for (r = 0; r < 2; ++r) { 6632 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6633 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6634 } 6635 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6636 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6637 } else if ((p >= cStart) && (p < cMax)) { 6638 /* Interior cells add new cells, faces, edges, and vertex */ 6639 for (r = 0; r < 8; ++r) { 6640 newp = cStartNew + (p - cStart)*8 + r; 6641 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6642 } 6643 for (r = 0; r < 12; ++r) { 6644 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6645 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6646 } 6647 for (r = 0; r < 6; ++r) { 6648 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6649 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6650 } 6651 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6652 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6653 } else if ((p >= cMax) && (p < cEnd)) { 6654 /* Hybrid cells add new cells, faces, and edges */ 6655 for (r = 0; r < 4; ++r) { 6656 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6657 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6658 } 6659 for (r = 0; r < 4; ++r) { 6660 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6661 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6662 } 6663 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6664 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6665 } 6666 break; 6667 default: 6668 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6669 } 6670 } 6671 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6672 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6673 } 6674 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6675 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6676 if (0) { 6677 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6678 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6679 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6680 } 6681 } 6682 PetscFunctionReturn(0); 6683 } 6684 6685 #undef __FUNCT__ 6686 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6687 /* This will only work for interpolated meshes */ 6688 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6689 { 6690 DM rdm; 6691 PetscInt *depthSize; 6692 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6693 PetscErrorCode ierr; 6694 6695 PetscFunctionBegin; 6696 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6697 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6698 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6699 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 6700 /* Calculate number of new points of each depth */ 6701 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6702 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 6703 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 6704 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6705 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6706 /* Step 1: Set chart */ 6707 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6708 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6709 /* Step 2: Set cone/support sizes */ 6710 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6711 /* Step 3: Setup refined DM */ 6712 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6713 /* Step 4: Set cones and supports */ 6714 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6715 /* Step 5: Stratify */ 6716 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6717 /* Step 6: Create pointSF */ 6718 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6719 /* Step 7: Set coordinates for vertices */ 6720 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6721 /* Step 8: Create labels */ 6722 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6723 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6724 6725 *dmRefined = rdm; 6726 PetscFunctionReturn(0); 6727 } 6728 6729 #undef __FUNCT__ 6730 #define __FUNCT__ "DMPlexCreateCoarsePointIS" 6731 /*@ 6732 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 6733 6734 Input Parameter: 6735 . dm - The coarse DM 6736 6737 Output Parameter: 6738 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 6739 6740 Level: developer 6741 6742 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 6743 @*/ 6744 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 6745 { 6746 CellRefiner cellRefiner; 6747 PetscInt *depthSize, *fpoints; 6748 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6749 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 6750 PetscErrorCode ierr; 6751 6752 PetscFunctionBegin; 6753 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6754 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6755 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6756 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 6757 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 6758 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6759 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6760 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 6761 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 6762 switch (cellRefiner) { 6763 case REFINER_SIMPLEX_1D: 6764 case REFINER_SIMPLEX_2D: 6765 case REFINER_HYBRID_SIMPLEX_2D: 6766 case REFINER_HEX_2D: 6767 case REFINER_HYBRID_HEX_2D: 6768 case REFINER_SIMPLEX_3D: 6769 case REFINER_HYBRID_SIMPLEX_3D: 6770 case REFINER_HEX_3D: 6771 case REFINER_HYBRID_HEX_3D: 6772 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 6773 break; 6774 default: 6775 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 6776 } 6777 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 6778 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6779 PetscFunctionReturn(0); 6780 } 6781 6782 #undef __FUNCT__ 6783 #define __FUNCT__ "DMPlexSetRefinementUniform" 6784 /*@ 6785 DMPlexSetRefinementUniform - Set the flag for uniform refinement 6786 6787 Input Parameters: 6788 + dm - The DM 6789 - refinementUniform - The flag for uniform refinement 6790 6791 Level: developer 6792 6793 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6794 @*/ 6795 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6796 { 6797 DM_Plex *mesh = (DM_Plex*) dm->data; 6798 6799 PetscFunctionBegin; 6800 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6801 mesh->refinementUniform = refinementUniform; 6802 PetscFunctionReturn(0); 6803 } 6804 6805 #undef __FUNCT__ 6806 #define __FUNCT__ "DMPlexGetRefinementUniform" 6807 /*@ 6808 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 6809 6810 Input Parameter: 6811 . dm - The DM 6812 6813 Output Parameter: 6814 . refinementUniform - The flag for uniform refinement 6815 6816 Level: developer 6817 6818 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6819 @*/ 6820 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6821 { 6822 DM_Plex *mesh = (DM_Plex*) dm->data; 6823 6824 PetscFunctionBegin; 6825 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6826 PetscValidPointer(refinementUniform, 2); 6827 *refinementUniform = mesh->refinementUniform; 6828 PetscFunctionReturn(0); 6829 } 6830 6831 #undef __FUNCT__ 6832 #define __FUNCT__ "DMPlexSetRefinementLimit" 6833 /*@ 6834 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 6835 6836 Input Parameters: 6837 + dm - The DM 6838 - refinementLimit - The maximum cell volume in the refined mesh 6839 6840 Level: developer 6841 6842 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6843 @*/ 6844 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6845 { 6846 DM_Plex *mesh = (DM_Plex*) dm->data; 6847 6848 PetscFunctionBegin; 6849 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6850 mesh->refinementLimit = refinementLimit; 6851 PetscFunctionReturn(0); 6852 } 6853 6854 #undef __FUNCT__ 6855 #define __FUNCT__ "DMPlexGetRefinementLimit" 6856 /*@ 6857 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 6858 6859 Input Parameter: 6860 . dm - The DM 6861 6862 Output Parameter: 6863 . refinementLimit - The maximum cell volume in the refined mesh 6864 6865 Level: developer 6866 6867 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6868 @*/ 6869 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6870 { 6871 DM_Plex *mesh = (DM_Plex*) dm->data; 6872 6873 PetscFunctionBegin; 6874 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6875 PetscValidPointer(refinementLimit, 2); 6876 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6877 *refinementLimit = mesh->refinementLimit; 6878 PetscFunctionReturn(0); 6879 } 6880 6881 #undef __FUNCT__ 6882 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6883 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6884 { 6885 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 6886 PetscErrorCode ierr; 6887 6888 PetscFunctionBegin; 6889 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6890 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6891 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 6892 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6893 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 6894 switch (dim) { 6895 case 1: 6896 switch (coneSize) { 6897 case 2: 6898 *cellRefiner = REFINER_SIMPLEX_1D; 6899 break; 6900 default: 6901 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6902 } 6903 break; 6904 case 2: 6905 switch (coneSize) { 6906 case 3: 6907 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 6908 else *cellRefiner = REFINER_SIMPLEX_2D; 6909 break; 6910 case 4: 6911 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 6912 else *cellRefiner = REFINER_HEX_2D; 6913 break; 6914 default: 6915 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6916 } 6917 break; 6918 case 3: 6919 switch (coneSize) { 6920 case 4: 6921 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 6922 else *cellRefiner = REFINER_SIMPLEX_3D; 6923 break; 6924 case 6: 6925 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 6926 else *cellRefiner = REFINER_HEX_3D; 6927 break; 6928 default: 6929 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6930 } 6931 break; 6932 default: 6933 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6934 } 6935 PetscFunctionReturn(0); 6936 } 6937