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 1: 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 2: 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_2D: 183 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 184 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 185 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 186 break; 187 case REFINER_HYBRID_SIMPLEX_2D: 188 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 189 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 190 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 191 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 */ 192 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 193 break; 194 case REFINER_HEX_2D: 195 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 196 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 197 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 198 break; 199 case REFINER_HYBRID_HEX_2D: 200 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 201 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 202 /* Quadrilateral */ 203 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 204 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 205 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 206 /* Segment Prisms */ 207 depthSize[0] += 0; /* No hybrid vertices */ 208 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 209 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 210 break; 211 case REFINER_SIMPLEX_3D: 212 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 213 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 */ 214 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 215 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 216 break; 217 case REFINER_HYBRID_SIMPLEX_3D: 218 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 219 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 220 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 221 /* Tetrahedra */ 222 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 223 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 */ 224 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 225 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 226 /* Triangular Prisms */ 227 depthSize[0] += 0; /* No hybrid vertices */ 228 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 229 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 230 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 231 break; 232 case REFINER_HEX_3D: 233 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 234 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 */ 235 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 236 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 237 break; 238 case REFINER_HYBRID_HEX_3D: 239 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 240 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 241 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 242 /* Hexahedra */ 243 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 244 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 */ 245 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 246 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 247 /* Quadrilateral Prisms */ 248 depthSize[0] += 0; /* No hybrid vertices */ 249 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 250 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 251 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 252 break; 253 default: 254 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 255 } 256 PetscFunctionReturn(0); 257 } 258 259 /* Return triangle edge for orientation o, if it is r for o == 0 */ 260 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 261 return (o < 0 ? 2-(o+r) : o+r)%3; 262 } 263 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 264 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 265 } 266 267 /* Return triangle subface for orientation o, if it is r for o == 0 */ 268 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 269 return (o < 0 ? 3-(o+r) : o+r)%3; 270 } 271 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 272 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 273 } 274 275 /* I HAVE NO IDEA: Return ??? for orientation o, if it is r for o == 0 */ 276 PETSC_STATIC_INLINE PetscInt GetTetSomething_Static(PetscInt o, PetscInt r) { 277 return (o < 0 ? 1-(o+r) : o+r)%3; 278 } 279 PETSC_STATIC_INLINE PetscInt GetTetSomethingInverse_Static(PetscInt o, PetscInt s) { 280 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 281 } 282 283 284 /* Return quad edge for orientation o, if it is r for o == 0 */ 285 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 286 return (o < 0 ? 3-(o+r) : o+r)%4; 287 } 288 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 289 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 290 } 291 292 /* Return quad subface for orientation o, if it is r for o == 0 */ 293 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 294 return (o < 0 ? 4-(o+r) : o+r)%4; 295 } 296 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 297 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 298 } 299 300 #undef __FUNCT__ 301 #define __FUNCT__ "CellRefinerSetConeSizes" 302 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 303 { 304 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 305 PetscErrorCode ierr; 306 307 PetscFunctionBegin; 308 if (!refiner) PetscFunctionReturn(0); 309 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 310 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 311 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 312 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 313 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 314 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 315 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 316 switch (refiner) { 317 case REFINER_SIMPLEX_2D: 318 /* All cells have 3 faces */ 319 for (c = cStart; c < cEnd; ++c) { 320 for (r = 0; r < 4; ++r) { 321 const PetscInt newp = (c - cStart)*4 + r; 322 323 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 324 } 325 } 326 /* Split faces have 2 vertices and the same cells as the parent */ 327 for (f = fStart; f < fEnd; ++f) { 328 for (r = 0; r < 2; ++r) { 329 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 330 PetscInt size; 331 332 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 333 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 334 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 335 } 336 } 337 /* Interior faces have 2 vertices and 2 cells */ 338 for (c = cStart; c < cEnd; ++c) { 339 for (r = 0; r < 3; ++r) { 340 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 341 342 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 343 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 344 } 345 } 346 /* Old vertices have identical supports */ 347 for (v = vStart; v < vEnd; ++v) { 348 const PetscInt newp = vStartNew + (v - vStart); 349 PetscInt size; 350 351 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 352 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 353 } 354 /* Face vertices have 2 + cells*2 supports */ 355 for (f = fStart; f < fEnd; ++f) { 356 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 357 PetscInt size; 358 359 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 360 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 361 } 362 break; 363 case REFINER_HEX_2D: 364 /* All cells have 4 faces */ 365 for (c = cStart; c < cEnd; ++c) { 366 for (r = 0; r < 4; ++r) { 367 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 368 369 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 370 } 371 } 372 /* Split faces have 2 vertices and the same cells as the parent */ 373 for (f = fStart; f < fEnd; ++f) { 374 for (r = 0; r < 2; ++r) { 375 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 376 PetscInt size; 377 378 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 379 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 380 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 381 } 382 } 383 /* Interior faces have 2 vertices and 2 cells */ 384 for (c = cStart; c < cEnd; ++c) { 385 for (r = 0; r < 4; ++r) { 386 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 387 388 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 389 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 390 } 391 } 392 /* Old vertices have identical supports */ 393 for (v = vStart; v < vEnd; ++v) { 394 const PetscInt newp = vStartNew + (v - vStart); 395 PetscInt size; 396 397 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 398 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 399 } 400 /* Face vertices have 2 + cells supports */ 401 for (f = fStart; f < fEnd; ++f) { 402 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 403 PetscInt size; 404 405 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 406 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 407 } 408 /* Cell vertices have 4 supports */ 409 for (c = cStart; c < cEnd; ++c) { 410 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 411 412 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 413 } 414 break; 415 case REFINER_HYBRID_SIMPLEX_2D: 416 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 417 cMax = PetscMin(cEnd, cMax); 418 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 419 fMax = PetscMin(fEnd, fMax); 420 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 421 /* Interior cells have 3 faces */ 422 for (c = cStart; c < cMax; ++c) { 423 for (r = 0; r < 4; ++r) { 424 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 425 426 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 427 } 428 } 429 /* Hybrid cells have 4 faces */ 430 for (c = cMax; c < cEnd; ++c) { 431 for (r = 0; r < 2; ++r) { 432 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 433 434 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 435 } 436 } 437 /* Interior split faces have 2 vertices and the same cells as the parent */ 438 for (f = fStart; f < fMax; ++f) { 439 for (r = 0; r < 2; ++r) { 440 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 441 PetscInt size; 442 443 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 444 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 445 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 446 } 447 } 448 /* Interior cell faces have 2 vertices and 2 cells */ 449 for (c = cStart; c < cMax; ++c) { 450 for (r = 0; r < 3; ++r) { 451 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 452 453 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 454 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 455 } 456 } 457 /* Hybrid faces have 2 vertices and the same cells */ 458 for (f = fMax; f < fEnd; ++f) { 459 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 460 PetscInt size; 461 462 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 463 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 464 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 465 } 466 /* Hybrid cell faces have 2 vertices and 2 cells */ 467 for (c = cMax; c < cEnd; ++c) { 468 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 469 470 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 471 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 472 } 473 /* Old vertices have identical supports */ 474 for (v = vStart; v < vEnd; ++v) { 475 const PetscInt newp = vStartNew + (v - vStart); 476 PetscInt size; 477 478 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 479 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 480 } 481 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 482 for (f = fStart; f < fMax; ++f) { 483 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 484 const PetscInt *support; 485 PetscInt size, newSize = 2, s; 486 487 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 488 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 489 for (s = 0; s < size; ++s) { 490 if (support[s] >= cMax) newSize += 1; 491 else newSize += 2; 492 } 493 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 494 } 495 break; 496 case REFINER_HYBRID_HEX_2D: 497 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 498 cMax = PetscMin(cEnd, cMax); 499 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 500 fMax = PetscMin(fEnd, fMax); 501 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 502 /* Interior cells have 4 faces */ 503 for (c = cStart; c < cMax; ++c) { 504 for (r = 0; r < 4; ++r) { 505 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 506 507 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 508 } 509 } 510 /* Hybrid cells have 4 faces */ 511 for (c = cMax; c < cEnd; ++c) { 512 for (r = 0; r < 2; ++r) { 513 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 514 515 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 516 } 517 } 518 /* Interior split faces have 2 vertices and the same cells as the parent */ 519 for (f = fStart; f < fMax; ++f) { 520 for (r = 0; r < 2; ++r) { 521 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 522 PetscInt size; 523 524 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 525 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 526 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 527 } 528 } 529 /* Interior cell faces have 2 vertices and 2 cells */ 530 for (c = cStart; c < cMax; ++c) { 531 for (r = 0; r < 4; ++r) { 532 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 533 534 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 535 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 536 } 537 } 538 /* Hybrid faces have 2 vertices and the same cells */ 539 for (f = fMax; f < fEnd; ++f) { 540 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 541 PetscInt size; 542 543 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 544 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 545 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 546 } 547 /* Hybrid cell faces have 2 vertices and 2 cells */ 548 for (c = cMax; c < cEnd; ++c) { 549 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 550 551 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 552 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 553 } 554 /* Old vertices have identical supports */ 555 for (v = vStart; v < vEnd; ++v) { 556 const PetscInt newp = vStartNew + (v - vStart); 557 PetscInt size; 558 559 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 560 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 561 } 562 /* Face vertices have 2 + cells supports */ 563 for (f = fStart; f < fMax; ++f) { 564 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 565 PetscInt size; 566 567 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 568 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 569 } 570 /* Cell vertices have 4 supports */ 571 for (c = cStart; c < cMax; ++c) { 572 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 573 574 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 575 } 576 break; 577 case REFINER_SIMPLEX_3D: 578 /* All cells have 4 faces */ 579 for (c = cStart; c < cEnd; ++c) { 580 for (r = 0; r < 8; ++r) { 581 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 582 583 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 584 } 585 } 586 /* Split faces have 3 edges and the same cells as the parent */ 587 for (f = fStart; f < fEnd; ++f) { 588 for (r = 0; r < 4; ++r) { 589 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 590 PetscInt size; 591 592 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 593 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 594 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 595 } 596 } 597 /* Interior cell faces have 3 edges and 2 cells */ 598 for (c = cStart; c < cEnd; ++c) { 599 for (r = 0; r < 8; ++r) { 600 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 601 602 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 603 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 604 } 605 } 606 /* Split edges have 2 vertices and the same faces */ 607 for (e = eStart; e < eEnd; ++e) { 608 for (r = 0; r < 2; ++r) { 609 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 610 PetscInt size; 611 612 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 613 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 614 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 615 } 616 } 617 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 618 for (f = fStart; f < fEnd; ++f) { 619 for (r = 0; r < 3; ++r) { 620 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 621 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 622 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 623 624 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 625 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 626 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 627 for (s = 0; s < supportSize; ++s) { 628 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 629 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 630 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 631 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 632 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 633 er = GetTetSomethingInverse_Static(ornt[c], r); 634 if (er == eint[c]) { 635 intFaces += 1; 636 } else { 637 intFaces += 2; 638 } 639 } 640 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 641 } 642 } 643 /* Interior cell edges have 2 vertices and 4 faces */ 644 for (c = cStart; c < cEnd; ++c) { 645 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 646 647 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 648 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 649 } 650 /* Old vertices have identical supports */ 651 for (v = vStart; v < vEnd; ++v) { 652 const PetscInt newp = vStartNew + (v - vStart); 653 PetscInt size; 654 655 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 656 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 657 } 658 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 659 for (e = eStart; e < eEnd; ++e) { 660 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 661 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 662 663 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 664 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 665 for (s = 0; s < starSize*2; s += 2) { 666 const PetscInt *cone, *ornt; 667 PetscInt e01, e23; 668 669 if ((star[s] >= cStart) && (star[s] < cEnd)) { 670 /* Check edge 0-1 */ 671 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 672 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 673 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 674 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 675 /* Check edge 2-3 */ 676 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 677 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 678 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 679 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 680 if ((e01 == e) || (e23 == e)) ++cellSize; 681 } 682 } 683 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 684 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 685 } 686 break; 687 case REFINER_HYBRID_SIMPLEX_3D: 688 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 689 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 690 /* Interior cells have 4 faces */ 691 for (c = cStart; c < cMax; ++c) { 692 for (r = 0; r < 8; ++r) { 693 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 694 695 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 696 } 697 } 698 /* Hybrid cells have 5 faces */ 699 for (c = cMax; c < cEnd; ++c) { 700 for (r = 0; r < 4; ++r) { 701 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 702 703 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 704 } 705 } 706 /* Interior split faces have 3 edges and the same cells as the parent */ 707 for (f = fStart; f < fMax; ++f) { 708 for (r = 0; r < 4; ++r) { 709 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 710 PetscInt size; 711 712 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 713 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 714 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 715 } 716 } 717 /* Interior cell faces have 3 edges and 2 cells */ 718 for (c = cStart; c < cMax; ++c) { 719 for (r = 0; r < 8; ++r) { 720 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 721 722 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 723 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 724 } 725 } 726 /* Hybrid split faces have 4 edges and the same cells as the parent */ 727 for (f = fMax; f < fEnd; ++f) { 728 for (r = 0; r < 2; ++r) { 729 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 730 PetscInt size; 731 732 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 733 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 734 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 735 } 736 } 737 /* Hybrid cells faces have 4 edges and 2 cells */ 738 for (c = cMax; c < cEnd; ++c) { 739 for (r = 0; r < 3; ++r) { 740 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 741 742 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 743 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 744 } 745 } 746 /* Interior split edges have 2 vertices and the same faces */ 747 for (e = eStart; e < eMax; ++e) { 748 for (r = 0; r < 2; ++r) { 749 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 750 PetscInt size; 751 752 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 753 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 754 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 755 } 756 } 757 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 758 for (f = fStart; f < fMax; ++f) { 759 for (r = 0; r < 3; ++r) { 760 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 761 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 762 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 763 764 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 765 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 766 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 767 for (s = 0; s < supportSize; ++s) { 768 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 769 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 770 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 771 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 772 if (support[s] < cMax) { 773 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 774 er = GetTetSomethingInverse_Static(ornt[c], r); 775 if (er == eint[c]) { 776 intFaces += 1; 777 } else { 778 intFaces += 2; 779 } 780 } else { 781 intFaces += 1; 782 } 783 } 784 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 785 } 786 } 787 /* Interior cell edges have 2 vertices and 4 faces */ 788 for (c = cStart; c < cMax; ++c) { 789 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 790 791 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 792 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 793 } 794 /* Hybrid edges have 2 vertices and the same faces */ 795 for (e = eMax; e < eEnd; ++e) { 796 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 797 PetscInt size; 798 799 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 800 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 801 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 802 } 803 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 804 for (f = fMax; f < fEnd; ++f) { 805 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 806 PetscInt size; 807 808 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 809 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 810 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 811 } 812 /* Interior vertices have identical supports */ 813 for (v = vStart; v < vEnd; ++v) { 814 const PetscInt newp = vStartNew + (v - vStart); 815 PetscInt size; 816 817 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 818 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 819 } 820 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 821 for (e = eStart; e < eMax; ++e) { 822 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 823 const PetscInt *support; 824 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 825 826 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 827 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 828 for (s = 0; s < size; ++s) { 829 if (support[s] < fMax) faceSize += 2; 830 else faceSize += 1; 831 } 832 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 833 for (s = 0; s < starSize*2; s += 2) { 834 const PetscInt *cone, *ornt; 835 PetscInt e01, e23; 836 837 if ((star[s] >= cStart) && (star[s] < cMax)) { 838 /* Check edge 0-1 */ 839 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 840 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 841 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 842 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 843 /* Check edge 2-3 */ 844 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 845 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 846 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 847 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 848 if ((e01 == e) || (e23 == e)) ++cellSize; 849 } 850 } 851 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 852 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 853 } 854 break; 855 case REFINER_HEX_3D: 856 /* All cells have 6 faces */ 857 for (c = cStart; c < cEnd; ++c) { 858 for (r = 0; r < 8; ++r) { 859 const PetscInt newp = (c - cStart)*8 + r; 860 861 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 862 } 863 } 864 /* Split faces have 4 edges and the same cells as the parent */ 865 for (f = fStart; f < fEnd; ++f) { 866 for (r = 0; r < 4; ++r) { 867 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 868 PetscInt size; 869 870 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 871 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 872 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 873 } 874 } 875 /* Interior faces have 4 edges and 2 cells */ 876 for (c = cStart; c < cEnd; ++c) { 877 for (r = 0; r < 12; ++r) { 878 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 879 880 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 881 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 882 } 883 } 884 /* Split edges have 2 vertices and the same faces as the parent */ 885 for (e = eStart; e < eEnd; ++e) { 886 for (r = 0; r < 2; ++r) { 887 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 888 PetscInt size; 889 890 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 891 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 892 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 893 } 894 } 895 /* Face edges have 2 vertices and 2+cells faces */ 896 for (f = fStart; f < fEnd; ++f) { 897 for (r = 0; r < 4; ++r) { 898 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 899 PetscInt size; 900 901 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 902 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 903 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 904 } 905 } 906 /* Cell edges have 2 vertices and 4 faces */ 907 for (c = cStart; c < cEnd; ++c) { 908 for (r = 0; r < 6; ++r) { 909 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 910 911 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 912 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 913 } 914 } 915 /* Old vertices have identical supports */ 916 for (v = vStart; v < vEnd; ++v) { 917 const PetscInt newp = vStartNew + (v - vStart); 918 PetscInt size; 919 920 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 921 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 922 } 923 /* Edge vertices have 2 + faces supports */ 924 for (e = eStart; e < eEnd; ++e) { 925 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 926 PetscInt size; 927 928 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 929 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 930 } 931 /* Face vertices have 4 + cells supports */ 932 for (f = fStart; f < fEnd; ++f) { 933 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 934 PetscInt size; 935 936 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 937 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 938 } 939 /* Cell vertices have 6 supports */ 940 for (c = cStart; c < cEnd; ++c) { 941 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 942 943 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 944 } 945 break; 946 case REFINER_HYBRID_HEX_3D: 947 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 948 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 949 /* Interior cells have 6 faces */ 950 for (c = cStart; c < cMax; ++c) { 951 for (r = 0; r < 8; ++r) { 952 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 953 954 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 955 } 956 } 957 /* Hybrid cells have 6 faces */ 958 for (c = cMax; c < cEnd; ++c) { 959 for (r = 0; r < 4; ++r) { 960 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 961 962 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 963 } 964 } 965 /* Interior split faces have 4 edges and the same cells as the parent */ 966 for (f = fStart; f < fMax; ++f) { 967 for (r = 0; r < 4; ++r) { 968 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 969 PetscInt size; 970 971 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 972 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 973 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 974 } 975 } 976 /* Interior cell faces have 4 edges and 2 cells */ 977 for (c = cStart; c < cMax; ++c) { 978 for (r = 0; r < 12; ++r) { 979 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 980 981 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 982 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 983 } 984 } 985 /* Hybrid split faces have 4 edges and the same cells as the parent */ 986 for (f = fMax; f < fEnd; ++f) { 987 for (r = 0; r < 2; ++r) { 988 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 989 PetscInt size; 990 991 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 992 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 993 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 994 } 995 } 996 /* Hybrid cells faces have 4 edges and 2 cells */ 997 for (c = cMax; c < cEnd; ++c) { 998 for (r = 0; r < 4; ++r) { 999 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1000 1001 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1002 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1003 } 1004 } 1005 /* Interior split edges have 2 vertices and the same faces as the parent */ 1006 for (e = eStart; e < eMax; ++e) { 1007 for (r = 0; r < 2; ++r) { 1008 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1009 PetscInt size; 1010 1011 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1012 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1013 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1014 } 1015 } 1016 /* Interior face edges have 2 vertices and 2+cells faces */ 1017 for (f = fStart; f < fMax; ++f) { 1018 for (r = 0; r < 4; ++r) { 1019 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1020 PetscInt size; 1021 1022 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1023 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1024 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1025 } 1026 } 1027 /* Interior cell edges have 2 vertices and 4 faces */ 1028 for (c = cStart; c < cMax; ++c) { 1029 for (r = 0; r < 6; ++r) { 1030 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1031 1032 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1033 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1034 } 1035 } 1036 /* Hybrid edges have 2 vertices and the same faces */ 1037 for (e = eMax; e < eEnd; ++e) { 1038 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1039 PetscInt size; 1040 1041 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1042 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1043 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1044 } 1045 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1046 for (f = fMax; f < fEnd; ++f) { 1047 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 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 /* Hybrid cell edges have 2 vertices and 4 faces */ 1055 for (c = cMax; c < cEnd; ++c) { 1056 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1057 1058 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1059 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1060 } 1061 /* Interior vertices have identical supports */ 1062 for (v = vStart; v < vEnd; ++v) { 1063 const PetscInt newp = vStartNew + (v - vStart); 1064 PetscInt size; 1065 1066 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1067 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1068 } 1069 /* Interior edge vertices have 2 + faces supports */ 1070 for (e = eStart; e < eMax; ++e) { 1071 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1072 PetscInt size; 1073 1074 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1075 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1076 } 1077 /* Interior face vertices have 4 + cells supports */ 1078 for (f = fStart; f < fMax; ++f) { 1079 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1080 PetscInt size; 1081 1082 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1083 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1084 } 1085 /* Interior cell vertices have 6 supports */ 1086 for (c = cStart; c < cMax; ++c) { 1087 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1088 1089 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1090 } 1091 break; 1092 default: 1093 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1094 } 1095 PetscFunctionReturn(0); 1096 } 1097 1098 #undef __FUNCT__ 1099 #define __FUNCT__ "CellRefinerSetCones" 1100 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1101 { 1102 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1103 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1104 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1105 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 1106 PetscErrorCode ierr; 1107 1108 PetscFunctionBegin; 1109 if (!refiner) PetscFunctionReturn(0); 1110 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1111 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1112 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1113 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1114 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1115 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1116 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1117 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1118 switch (refiner) { 1119 case REFINER_SIMPLEX_2D: 1120 /* 1121 2 1122 |\ 1123 | \ 1124 | \ 1125 | \ 1126 | C \ 1127 | \ 1128 | \ 1129 2---1---1 1130 |\ D / \ 1131 | 2 0 \ 1132 |A \ / B \ 1133 0---0-------1 1134 */ 1135 /* All cells have 3 faces */ 1136 for (c = cStart; c < cEnd; ++c) { 1137 const PetscInt newp = cStartNew + (c - cStart)*4; 1138 const PetscInt *cone, *ornt; 1139 PetscInt coneNew[3], orntNew[3]; 1140 1141 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1142 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1143 /* A triangle */ 1144 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1145 orntNew[0] = ornt[0]; 1146 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1147 orntNew[1] = -2; 1148 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1149 orntNew[2] = ornt[2]; 1150 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1151 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1152 #if 1 1153 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); 1154 for (p = 0; p < 3; ++p) { 1155 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); 1156 } 1157 #endif 1158 /* B triangle */ 1159 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1160 orntNew[0] = ornt[0]; 1161 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1162 orntNew[1] = ornt[1]; 1163 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1164 orntNew[2] = -2; 1165 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1166 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1167 #if 1 1168 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); 1169 for (p = 0; p < 3; ++p) { 1170 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); 1171 } 1172 #endif 1173 /* C triangle */ 1174 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1175 orntNew[0] = -2; 1176 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1177 orntNew[1] = ornt[1]; 1178 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1179 orntNew[2] = ornt[2]; 1180 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1181 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1182 #if 1 1183 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); 1184 for (p = 0; p < 3; ++p) { 1185 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); 1186 } 1187 #endif 1188 /* D triangle */ 1189 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1190 orntNew[0] = 0; 1191 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1192 orntNew[1] = 0; 1193 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1194 orntNew[2] = 0; 1195 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1196 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1197 #if 1 1198 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); 1199 for (p = 0; p < 3; ++p) { 1200 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); 1201 } 1202 #endif 1203 } 1204 /* Split faces have 2 vertices and the same cells as the parent */ 1205 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1206 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1207 for (f = fStart; f < fEnd; ++f) { 1208 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1209 1210 for (r = 0; r < 2; ++r) { 1211 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1212 const PetscInt *cone, *ornt, *support; 1213 PetscInt coneNew[2], coneSize, c, supportSize, s; 1214 1215 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1216 coneNew[0] = vStartNew + (cone[0] - vStart); 1217 coneNew[1] = vStartNew + (cone[1] - vStart); 1218 coneNew[(r+1)%2] = newv; 1219 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1220 #if 1 1221 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1222 for (p = 0; p < 2; ++p) { 1223 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); 1224 } 1225 #endif 1226 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1227 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1228 for (s = 0; s < supportSize; ++s) { 1229 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1230 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1231 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1232 for (c = 0; c < coneSize; ++c) { 1233 if (cone[c] == f) break; 1234 } 1235 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1236 } 1237 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1238 #if 1 1239 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1240 for (p = 0; p < supportSize; ++p) { 1241 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); 1242 } 1243 #endif 1244 } 1245 } 1246 /* Interior faces have 2 vertices and 2 cells */ 1247 for (c = cStart; c < cEnd; ++c) { 1248 const PetscInt *cone; 1249 1250 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1251 for (r = 0; r < 3; ++r) { 1252 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1253 PetscInt coneNew[2]; 1254 PetscInt supportNew[2]; 1255 1256 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1257 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1258 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1259 #if 1 1260 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1261 for (p = 0; p < 2; ++p) { 1262 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); 1263 } 1264 #endif 1265 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1266 supportNew[1] = (c - cStart)*4 + 3; 1267 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1268 #if 1 1269 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1270 for (p = 0; p < 2; ++p) { 1271 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); 1272 } 1273 #endif 1274 } 1275 } 1276 /* Old vertices have identical supports */ 1277 for (v = vStart; v < vEnd; ++v) { 1278 const PetscInt newp = vStartNew + (v - vStart); 1279 const PetscInt *support, *cone; 1280 PetscInt size, s; 1281 1282 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1283 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1284 for (s = 0; s < size; ++s) { 1285 PetscInt r = 0; 1286 1287 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1288 if (cone[1] == v) r = 1; 1289 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1290 } 1291 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1292 #if 1 1293 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1294 for (p = 0; p < size; ++p) { 1295 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); 1296 } 1297 #endif 1298 } 1299 /* Face vertices have 2 + cells*2 supports */ 1300 for (f = fStart; f < fEnd; ++f) { 1301 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1302 const PetscInt *cone, *support; 1303 PetscInt size, s; 1304 1305 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1306 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1307 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1308 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1309 for (s = 0; s < size; ++s) { 1310 PetscInt r = 0; 1311 1312 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1313 if (cone[1] == f) r = 1; 1314 else if (cone[2] == f) r = 2; 1315 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1316 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1317 } 1318 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1319 #if 1 1320 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1321 for (p = 0; p < 2+size*2; ++p) { 1322 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); 1323 } 1324 #endif 1325 } 1326 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1327 break; 1328 case REFINER_HEX_2D: 1329 /* 1330 3---------2---------2 1331 | | | 1332 | D 2 C | 1333 | | | 1334 3----3----0----1----1 1335 | | | 1336 | A 0 B | 1337 | | | 1338 0---------0---------1 1339 */ 1340 /* All cells have 4 faces */ 1341 for (c = cStart; c < cEnd; ++c) { 1342 const PetscInt newp = (c - cStart)*4; 1343 const PetscInt *cone, *ornt; 1344 PetscInt coneNew[4], orntNew[4]; 1345 1346 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1347 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1348 /* A quad */ 1349 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1350 orntNew[0] = ornt[0]; 1351 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1352 orntNew[1] = 0; 1353 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1354 orntNew[2] = -2; 1355 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1356 orntNew[3] = ornt[3]; 1357 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1358 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1359 #if 1 1360 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); 1361 for (p = 0; p < 4; ++p) { 1362 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); 1363 } 1364 #endif 1365 /* B quad */ 1366 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1367 orntNew[0] = ornt[0]; 1368 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1369 orntNew[1] = ornt[1]; 1370 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1371 orntNew[2] = 0; 1372 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1373 orntNew[3] = -2; 1374 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1375 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1376 #if 1 1377 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); 1378 for (p = 0; p < 4; ++p) { 1379 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); 1380 } 1381 #endif 1382 /* C quad */ 1383 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1384 orntNew[0] = -2; 1385 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1386 orntNew[1] = ornt[1]; 1387 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1388 orntNew[2] = ornt[2]; 1389 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1390 orntNew[3] = 0; 1391 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1392 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1393 #if 1 1394 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); 1395 for (p = 0; p < 4; ++p) { 1396 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); 1397 } 1398 #endif 1399 /* D quad */ 1400 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1401 orntNew[0] = 0; 1402 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1403 orntNew[1] = -2; 1404 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1405 orntNew[2] = ornt[2]; 1406 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1407 orntNew[3] = ornt[3]; 1408 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1409 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1410 #if 1 1411 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); 1412 for (p = 0; p < 4; ++p) { 1413 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); 1414 } 1415 #endif 1416 } 1417 /* Split faces have 2 vertices and the same cells as the parent */ 1418 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1419 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1420 for (f = fStart; f < fEnd; ++f) { 1421 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1422 1423 for (r = 0; r < 2; ++r) { 1424 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1425 const PetscInt *cone, *ornt, *support; 1426 PetscInt coneNew[2], coneSize, c, supportSize, s; 1427 1428 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1429 coneNew[0] = vStartNew + (cone[0] - vStart); 1430 coneNew[1] = vStartNew + (cone[1] - vStart); 1431 coneNew[(r+1)%2] = newv; 1432 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1433 #if 1 1434 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1435 for (p = 0; p < 2; ++p) { 1436 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); 1437 } 1438 #endif 1439 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1440 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1441 for (s = 0; s < supportSize; ++s) { 1442 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1443 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1444 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1445 for (c = 0; c < coneSize; ++c) { 1446 if (cone[c] == f) break; 1447 } 1448 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1449 } 1450 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1451 #if 1 1452 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1453 for (p = 0; p < supportSize; ++p) { 1454 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); 1455 } 1456 #endif 1457 } 1458 } 1459 /* Interior faces have 2 vertices and 2 cells */ 1460 for (c = cStart; c < cEnd; ++c) { 1461 const PetscInt *cone; 1462 PetscInt coneNew[2], supportNew[2]; 1463 1464 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1465 for (r = 0; r < 4; ++r) { 1466 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1467 1468 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1469 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1470 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1471 #if 1 1472 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1473 for (p = 0; p < 2; ++p) { 1474 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); 1475 } 1476 #endif 1477 supportNew[0] = (c - cStart)*4 + r; 1478 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1479 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1480 #if 1 1481 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1482 for (p = 0; p < 2; ++p) { 1483 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); 1484 } 1485 #endif 1486 } 1487 } 1488 /* Old vertices have identical supports */ 1489 for (v = vStart; v < vEnd; ++v) { 1490 const PetscInt newp = vStartNew + (v - vStart); 1491 const PetscInt *support, *cone; 1492 PetscInt size, s; 1493 1494 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1495 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1496 for (s = 0; s < size; ++s) { 1497 PetscInt r = 0; 1498 1499 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1500 if (cone[1] == v) r = 1; 1501 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1502 } 1503 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1504 #if 1 1505 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1506 for (p = 0; p < size; ++p) { 1507 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); 1508 } 1509 #endif 1510 } 1511 /* Face vertices have 2 + cells supports */ 1512 for (f = fStart; f < fEnd; ++f) { 1513 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1514 const PetscInt *cone, *support; 1515 PetscInt size, s; 1516 1517 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1518 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1519 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1520 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1521 for (s = 0; s < size; ++s) { 1522 PetscInt r = 0; 1523 1524 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1525 if (cone[1] == f) r = 1; 1526 else if (cone[2] == f) r = 2; 1527 else if (cone[3] == f) r = 3; 1528 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 1529 } 1530 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1531 #if 1 1532 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1533 for (p = 0; p < 2+size; ++p) { 1534 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 1535 } 1536 #endif 1537 } 1538 /* Cell vertices have 4 supports */ 1539 for (c = cStart; c < cEnd; ++c) { 1540 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1541 PetscInt supportNew[4]; 1542 1543 for (r = 0; r < 4; ++r) { 1544 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1545 } 1546 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1547 } 1548 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1549 break; 1550 case REFINER_HYBRID_SIMPLEX_2D: 1551 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1552 cMax = PetscMin(cEnd, cMax); 1553 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1554 fMax = PetscMin(fEnd, fMax); 1555 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1556 /* Interior cells have 3 faces */ 1557 for (c = cStart; c < cMax; ++c) { 1558 const PetscInt newp = cStartNew + (c - cStart)*4; 1559 const PetscInt *cone, *ornt; 1560 PetscInt coneNew[3], orntNew[3]; 1561 1562 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1563 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1564 /* A triangle */ 1565 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1566 orntNew[0] = ornt[0]; 1567 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1568 orntNew[1] = -2; 1569 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1570 orntNew[2] = ornt[2]; 1571 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1572 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1573 #if 1 1574 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); 1575 for (p = 0; p < 3; ++p) { 1576 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); 1577 } 1578 #endif 1579 /* B triangle */ 1580 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1581 orntNew[0] = ornt[0]; 1582 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1583 orntNew[1] = ornt[1]; 1584 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1585 orntNew[2] = -2; 1586 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1587 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1588 #if 1 1589 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); 1590 for (p = 0; p < 3; ++p) { 1591 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); 1592 } 1593 #endif 1594 /* C triangle */ 1595 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1596 orntNew[0] = -2; 1597 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1598 orntNew[1] = ornt[1]; 1599 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1600 orntNew[2] = ornt[2]; 1601 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1602 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1603 #if 1 1604 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); 1605 for (p = 0; p < 3; ++p) { 1606 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); 1607 } 1608 #endif 1609 /* D triangle */ 1610 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 1611 orntNew[0] = 0; 1612 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 1613 orntNew[1] = 0; 1614 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 1615 orntNew[2] = 0; 1616 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1617 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1618 #if 1 1619 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); 1620 for (p = 0; p < 3; ++p) { 1621 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); 1622 } 1623 #endif 1624 } 1625 /* 1626 2----3----3 1627 | | 1628 | B | 1629 | | 1630 0----4--- 1 1631 | | 1632 | A | 1633 | | 1634 0----2----1 1635 */ 1636 /* Hybrid cells have 4 faces */ 1637 for (c = cMax; c < cEnd; ++c) { 1638 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1639 const PetscInt *cone, *ornt; 1640 PetscInt coneNew[4], orntNew[4], r; 1641 1642 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1643 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1644 r = (ornt[0] < 0 ? 1 : 0); 1645 /* A quad */ 1646 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 1647 orntNew[0] = ornt[0]; 1648 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 1649 orntNew[1] = ornt[1]; 1650 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 1651 orntNew[2+r] = 0; 1652 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1653 orntNew[3-r] = 0; 1654 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1655 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1656 #if 1 1657 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); 1658 for (p = 0; p < 4; ++p) { 1659 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); 1660 } 1661 #endif 1662 /* B quad */ 1663 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 1664 orntNew[0] = ornt[0]; 1665 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 1666 orntNew[1] = ornt[1]; 1667 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1668 orntNew[2+r] = 0; 1669 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 1670 orntNew[3-r] = 0; 1671 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1672 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1673 #if 1 1674 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); 1675 for (p = 0; p < 4; ++p) { 1676 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); 1677 } 1678 #endif 1679 } 1680 /* Interior split faces have 2 vertices and the same cells as the parent */ 1681 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1682 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1683 for (f = fStart; f < fMax; ++f) { 1684 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1685 1686 for (r = 0; r < 2; ++r) { 1687 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1688 const PetscInt *cone, *ornt, *support; 1689 PetscInt coneNew[2], coneSize, c, supportSize, s; 1690 1691 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1692 coneNew[0] = vStartNew + (cone[0] - vStart); 1693 coneNew[1] = vStartNew + (cone[1] - vStart); 1694 coneNew[(r+1)%2] = newv; 1695 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1696 #if 1 1697 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1698 for (p = 0; p < 2; ++p) { 1699 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); 1700 } 1701 #endif 1702 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1703 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1704 for (s = 0; s < supportSize; ++s) { 1705 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1706 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1707 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1708 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 1709 if (support[s] >= cMax) { 1710 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 1711 } else { 1712 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1713 } 1714 } 1715 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1716 #if 1 1717 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1718 for (p = 0; p < supportSize; ++p) { 1719 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); 1720 } 1721 #endif 1722 } 1723 } 1724 /* Interior cell faces have 2 vertices and 2 cells */ 1725 for (c = cStart; c < cMax; ++c) { 1726 const PetscInt *cone; 1727 1728 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1729 for (r = 0; r < 3; ++r) { 1730 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 1731 PetscInt coneNew[2]; 1732 PetscInt supportNew[2]; 1733 1734 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1735 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1736 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1737 #if 1 1738 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1739 for (p = 0; p < 2; ++p) { 1740 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); 1741 } 1742 #endif 1743 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1744 supportNew[1] = (c - cStart)*4 + 3; 1745 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1746 #if 1 1747 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1748 for (p = 0; p < 2; ++p) { 1749 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); 1750 } 1751 #endif 1752 } 1753 } 1754 /* Interior hybrid faces have 2 vertices and the same cells */ 1755 for (f = fMax; f < fEnd; ++f) { 1756 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 1757 const PetscInt *cone, *ornt; 1758 const PetscInt *support; 1759 PetscInt coneNew[2]; 1760 PetscInt supportNew[2]; 1761 PetscInt size, s, r; 1762 1763 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1764 coneNew[0] = vStartNew + (cone[0] - vStart); 1765 coneNew[1] = vStartNew + (cone[1] - vStart); 1766 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1767 #if 1 1768 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1769 for (p = 0; p < 2; ++p) { 1770 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); 1771 } 1772 #endif 1773 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1774 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1775 for (s = 0; s < size; ++s) { 1776 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1777 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1778 for (r = 0; r < 2; ++r) { 1779 if (cone[r+2] == f) break; 1780 } 1781 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 1782 } 1783 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1784 #if 1 1785 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1786 for (p = 0; p < size; ++p) { 1787 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); 1788 } 1789 #endif 1790 } 1791 /* Cell hybrid faces have 2 vertices and 2 cells */ 1792 for (c = cMax; c < cEnd; ++c) { 1793 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 1794 const PetscInt *cone; 1795 PetscInt coneNew[2]; 1796 PetscInt supportNew[2]; 1797 1798 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1799 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 1800 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 1801 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1802 #if 1 1803 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1804 for (p = 0; p < 2; ++p) { 1805 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); 1806 } 1807 #endif 1808 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 1809 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 1810 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1811 #if 1 1812 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1813 for (p = 0; p < 2; ++p) { 1814 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); 1815 } 1816 #endif 1817 } 1818 /* Old vertices have identical supports */ 1819 for (v = vStart; v < vEnd; ++v) { 1820 const PetscInt newp = vStartNew + (v - vStart); 1821 const PetscInt *support, *cone; 1822 PetscInt size, s; 1823 1824 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1825 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1826 for (s = 0; s < size; ++s) { 1827 if (support[s] >= fMax) { 1828 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 1829 } else { 1830 PetscInt r = 0; 1831 1832 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1833 if (cone[1] == v) r = 1; 1834 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1835 } 1836 } 1837 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1838 #if 1 1839 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1840 for (p = 0; p < size; ++p) { 1841 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); 1842 } 1843 #endif 1844 } 1845 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 1846 for (f = fStart; f < fMax; ++f) { 1847 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1848 const PetscInt *cone, *support; 1849 PetscInt size, newSize = 2, s; 1850 1851 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1852 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1853 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1854 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1855 for (s = 0; s < size; ++s) { 1856 PetscInt r = 0; 1857 1858 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1859 if (support[s] >= cMax) { 1860 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 1861 1862 newSize += 1; 1863 } else { 1864 if (cone[1] == f) r = 1; 1865 else if (cone[2] == f) r = 2; 1866 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1867 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 1868 1869 newSize += 2; 1870 } 1871 } 1872 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1873 #if 1 1874 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1875 for (p = 0; p < newSize; ++p) { 1876 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); 1877 } 1878 #endif 1879 } 1880 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1881 break; 1882 case REFINER_HYBRID_HEX_2D: 1883 /* Hybrid Hex 2D */ 1884 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1885 cMax = PetscMin(cEnd, cMax); 1886 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1887 fMax = PetscMin(fEnd, fMax); 1888 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 1889 /* Interior cells have 4 faces */ 1890 for (c = cStart; c < cMax; ++c) { 1891 const PetscInt newp = cStartNew + (c - cStart)*4; 1892 const PetscInt *cone, *ornt; 1893 PetscInt coneNew[4], orntNew[4]; 1894 1895 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1896 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1897 /* A quad */ 1898 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1899 orntNew[0] = ornt[0]; 1900 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1901 orntNew[1] = 0; 1902 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1903 orntNew[2] = -2; 1904 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1905 orntNew[3] = ornt[3]; 1906 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1907 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1908 #if 1 1909 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); 1910 for (p = 0; p < 4; ++p) { 1911 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); 1912 } 1913 #endif 1914 /* B quad */ 1915 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1916 orntNew[0] = ornt[0]; 1917 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1918 orntNew[1] = ornt[1]; 1919 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1920 orntNew[2] = 0; 1921 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 1922 orntNew[3] = -2; 1923 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1924 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1925 #if 1 1926 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); 1927 for (p = 0; p < 4; ++p) { 1928 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); 1929 } 1930 #endif 1931 /* C quad */ 1932 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 1933 orntNew[0] = -2; 1934 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1935 orntNew[1] = ornt[1]; 1936 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1937 orntNew[2] = ornt[2]; 1938 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1939 orntNew[3] = 0; 1940 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1941 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1942 #if 1 1943 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); 1944 for (p = 0; p < 4; ++p) { 1945 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); 1946 } 1947 #endif 1948 /* D quad */ 1949 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 1950 orntNew[0] = 0; 1951 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 1952 orntNew[1] = -2; 1953 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1954 orntNew[2] = ornt[2]; 1955 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1956 orntNew[3] = ornt[3]; 1957 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1958 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1959 #if 1 1960 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); 1961 for (p = 0; p < 4; ++p) { 1962 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); 1963 } 1964 #endif 1965 } 1966 /* 1967 2----3----3 1968 | | 1969 | B | 1970 | | 1971 0----4--- 1 1972 | | 1973 | A | 1974 | | 1975 0----2----1 1976 */ 1977 /* Hybrid cells have 4 faces */ 1978 for (c = cMax; c < cEnd; ++c) { 1979 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 1980 const PetscInt *cone, *ornt; 1981 PetscInt coneNew[4], orntNew[4]; 1982 1983 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1984 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1985 /* A quad */ 1986 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1987 orntNew[0] = ornt[0]; 1988 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1989 orntNew[1] = ornt[1]; 1990 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 1991 orntNew[2] = 0; 1992 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 1993 orntNew[3] = 0; 1994 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1995 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1996 #if 1 1997 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); 1998 for (p = 0; p < 4; ++p) { 1999 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); 2000 } 2001 #endif 2002 /* B quad */ 2003 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2004 orntNew[0] = ornt[0]; 2005 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2006 orntNew[1] = ornt[1]; 2007 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2008 orntNew[2] = 0; 2009 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 2010 orntNew[3] = 0; 2011 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2012 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2013 #if 1 2014 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); 2015 for (p = 0; p < 4; ++p) { 2016 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); 2017 } 2018 #endif 2019 } 2020 /* Interior split faces have 2 vertices and the same cells as the parent */ 2021 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2022 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2023 for (f = fStart; f < fMax; ++f) { 2024 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2025 2026 for (r = 0; r < 2; ++r) { 2027 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2028 const PetscInt *cone, *ornt, *support; 2029 PetscInt coneNew[2], coneSize, c, supportSize, s; 2030 2031 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2032 coneNew[0] = vStartNew + (cone[0] - vStart); 2033 coneNew[1] = vStartNew + (cone[1] - vStart); 2034 coneNew[(r+1)%2] = newv; 2035 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2036 #if 1 2037 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2038 for (p = 0; p < 2; ++p) { 2039 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); 2040 } 2041 #endif 2042 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2043 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2044 for (s = 0; s < supportSize; ++s) { 2045 if (support[s] >= cMax) { 2046 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2047 } else { 2048 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2049 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2050 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2051 for (c = 0; c < coneSize; ++c) { 2052 if (cone[c] == f) break; 2053 } 2054 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2055 } 2056 } 2057 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2058 #if 1 2059 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2060 for (p = 0; p < supportSize; ++p) { 2061 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); 2062 } 2063 #endif 2064 } 2065 } 2066 /* Interior cell faces have 2 vertices and 2 cells */ 2067 for (c = cStart; c < cMax; ++c) { 2068 const PetscInt *cone; 2069 2070 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2071 for (r = 0; r < 4; ++r) { 2072 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2073 PetscInt coneNew[2], supportNew[2]; 2074 2075 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2076 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2077 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2078 #if 1 2079 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2080 for (p = 0; p < 2; ++p) { 2081 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); 2082 } 2083 #endif 2084 supportNew[0] = (c - cStart)*4 + r; 2085 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2086 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2087 #if 1 2088 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2089 for (p = 0; p < 2; ++p) { 2090 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); 2091 } 2092 #endif 2093 } 2094 } 2095 /* Hybrid faces have 2 vertices and the same cells */ 2096 for (f = fMax; f < fEnd; ++f) { 2097 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 2098 const PetscInt *cone, *support; 2099 PetscInt coneNew[2], supportNew[2]; 2100 PetscInt size, s, r; 2101 2102 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2103 coneNew[0] = vStartNew + (cone[0] - vStart); 2104 coneNew[1] = vStartNew + (cone[1] - vStart); 2105 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2106 #if 1 2107 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2108 for (p = 0; p < 2; ++p) { 2109 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); 2110 } 2111 #endif 2112 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2113 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2114 for (s = 0; s < size; ++s) { 2115 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2116 for (r = 0; r < 2; ++r) { 2117 if (cone[r+2] == f) break; 2118 } 2119 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2120 } 2121 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2122 #if 1 2123 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2124 for (p = 0; p < size; ++p) { 2125 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); 2126 } 2127 #endif 2128 } 2129 /* Cell hybrid faces have 2 vertices and 2 cells */ 2130 for (c = cMax; c < cEnd; ++c) { 2131 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2132 const PetscInt *cone; 2133 PetscInt coneNew[2], supportNew[2]; 2134 2135 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2136 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2137 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2138 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2139 #if 1 2140 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2141 for (p = 0; p < 2; ++p) { 2142 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); 2143 } 2144 #endif 2145 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2146 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2147 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2148 #if 1 2149 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2150 for (p = 0; p < 2; ++p) { 2151 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); 2152 } 2153 #endif 2154 } 2155 /* Old vertices have identical supports */ 2156 for (v = vStart; v < vEnd; ++v) { 2157 const PetscInt newp = vStartNew + (v - vStart); 2158 const PetscInt *support, *cone; 2159 PetscInt size, s; 2160 2161 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2162 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2163 for (s = 0; s < size; ++s) { 2164 if (support[s] >= fMax) { 2165 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2166 } else { 2167 PetscInt r = 0; 2168 2169 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2170 if (cone[1] == v) r = 1; 2171 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2172 } 2173 } 2174 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2175 #if 1 2176 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2177 for (p = 0; p < size; ++p) { 2178 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); 2179 } 2180 #endif 2181 } 2182 /* Face vertices have 2 + cells supports */ 2183 for (f = fStart; f < fMax; ++f) { 2184 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2185 const PetscInt *cone, *support; 2186 PetscInt size, s; 2187 2188 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2189 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2190 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2191 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2192 for (s = 0; s < size; ++s) { 2193 PetscInt r = 0; 2194 2195 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2196 if (support[s] >= cMax) { 2197 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2198 } else { 2199 if (cone[1] == f) r = 1; 2200 else if (cone[2] == f) r = 2; 2201 else if (cone[3] == f) r = 3; 2202 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2203 } 2204 } 2205 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2206 #if 1 2207 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2208 for (p = 0; p < 2+size; ++p) { 2209 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); 2210 } 2211 #endif 2212 } 2213 /* Cell vertices have 4 supports */ 2214 for (c = cStart; c < cMax; ++c) { 2215 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2216 PetscInt supportNew[4]; 2217 2218 for (r = 0; r < 4; ++r) { 2219 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2220 } 2221 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2222 } 2223 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2224 break; 2225 case REFINER_SIMPLEX_3D: 2226 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2227 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2228 for (c = cStart; c < cEnd; ++c) { 2229 const PetscInt newp = cStartNew + (c - cStart)*8; 2230 const PetscInt *cone, *ornt; 2231 PetscInt coneNew[4], orntNew[4]; 2232 2233 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2234 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2235 /* A tetrahedron: {0, a, c, d} */ 2236 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2237 orntNew[0] = ornt[0]; 2238 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2239 orntNew[1] = ornt[1]; 2240 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2241 orntNew[2] = ornt[2]; 2242 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2243 orntNew[3] = 0; 2244 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2245 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2246 #if 1 2247 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); 2248 for (p = 0; p < 4; ++p) { 2249 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); 2250 } 2251 #endif 2252 /* B tetrahedron: {a, 1, b, e} */ 2253 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2254 orntNew[0] = ornt[0]; 2255 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2256 orntNew[1] = ornt[1]; 2257 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2258 orntNew[2] = 0; 2259 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2260 orntNew[3] = ornt[3]; 2261 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2262 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2263 #if 1 2264 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); 2265 for (p = 0; p < 4; ++p) { 2266 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); 2267 } 2268 #endif 2269 /* C tetrahedron: {c, b, 2, f} */ 2270 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2271 orntNew[0] = ornt[0]; 2272 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2273 orntNew[1] = 0; 2274 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2275 orntNew[2] = ornt[2]; 2276 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2277 orntNew[3] = ornt[3]; 2278 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2279 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2280 #if 1 2281 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); 2282 for (p = 0; p < 4; ++p) { 2283 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); 2284 } 2285 #endif 2286 /* D tetrahedron: {d, e, f, 3} */ 2287 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2288 orntNew[0] = 0; 2289 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2290 orntNew[1] = ornt[1]; 2291 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2292 orntNew[2] = ornt[2]; 2293 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2294 orntNew[3] = ornt[3]; 2295 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2296 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2297 #if 1 2298 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); 2299 for (p = 0; p < 4; ++p) { 2300 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); 2301 } 2302 #endif 2303 /* A' tetrahedron: {d, a, c, f} */ 2304 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2305 orntNew[0] = -3; 2306 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2307 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2308 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2309 orntNew[2] = 0; 2310 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2311 orntNew[3] = 2; 2312 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2313 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2314 #if 1 2315 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); 2316 for (p = 0; p < 4; ++p) { 2317 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); 2318 } 2319 #endif 2320 /* B' tetrahedron: {e, b, a, f} */ 2321 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2322 orntNew[0] = -3; 2323 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2324 orntNew[1] = 1; 2325 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2326 orntNew[2] = 0; 2327 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2328 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2329 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2330 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2331 #if 1 2332 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); 2333 for (p = 0; p < 4; ++p) { 2334 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); 2335 } 2336 #endif 2337 /* C' tetrahedron: {b, f, c, a} */ 2338 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2339 orntNew[0] = -3; 2340 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2341 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2342 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2343 orntNew[2] = -3; 2344 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2345 orntNew[3] = -2; 2346 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2347 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2348 #if 1 2349 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); 2350 for (p = 0; p < 4; ++p) { 2351 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); 2352 } 2353 #endif 2354 /* D' tetrahedron: {f, e, d, a} */ 2355 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2356 orntNew[0] = -3; 2357 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2358 orntNew[1] = -3; 2359 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 2360 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 2361 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2362 orntNew[3] = -3; 2363 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2364 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2365 #if 1 2366 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); 2367 for (p = 0; p < 4; ++p) { 2368 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); 2369 } 2370 #endif 2371 } 2372 /* Split faces have 3 edges and the same cells as the parent */ 2373 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2374 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2375 for (f = fStart; f < fEnd; ++f) { 2376 const PetscInt newp = fStartNew + (f - fStart)*4; 2377 const PetscInt *cone, *ornt, *support; 2378 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2379 2380 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2381 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2382 /* A triangle */ 2383 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2384 orntNew[0] = ornt[0]; 2385 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2386 orntNew[1] = -2; 2387 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2388 orntNew[2] = ornt[2]; 2389 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2390 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2391 #if 1 2392 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); 2393 for (p = 0; p < 3; ++p) { 2394 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); 2395 } 2396 #endif 2397 /* B triangle */ 2398 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2399 orntNew[0] = ornt[0]; 2400 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2401 orntNew[1] = ornt[1]; 2402 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2403 orntNew[2] = -2; 2404 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2405 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2406 #if 1 2407 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); 2408 for (p = 0; p < 3; ++p) { 2409 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); 2410 } 2411 #endif 2412 /* C triangle */ 2413 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2414 orntNew[0] = -2; 2415 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2416 orntNew[1] = ornt[1]; 2417 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2418 orntNew[2] = ornt[2]; 2419 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2420 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2421 #if 1 2422 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); 2423 for (p = 0; p < 3; ++p) { 2424 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); 2425 } 2426 #endif 2427 /* D triangle */ 2428 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2429 orntNew[0] = 0; 2430 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2431 orntNew[1] = 0; 2432 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2433 orntNew[2] = 0; 2434 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2435 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2436 #if 1 2437 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); 2438 for (p = 0; p < 3; ++p) { 2439 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); 2440 } 2441 #endif 2442 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2443 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2444 for (r = 0; r < 4; ++r) { 2445 for (s = 0; s < supportSize; ++s) { 2446 PetscInt subf; 2447 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2448 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2449 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2450 for (c = 0; c < coneSize; ++c) { 2451 if (cone[c] == f) break; 2452 } 2453 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2454 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2455 } 2456 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2457 #if 1 2458 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); 2459 for (p = 0; p < supportSize; ++p) { 2460 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); 2461 } 2462 #endif 2463 } 2464 } 2465 /* Interior faces have 3 edges and 2 cells */ 2466 for (c = cStart; c < cEnd; ++c) { 2467 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2468 const PetscInt *cone, *ornt; 2469 PetscInt coneNew[3], orntNew[3]; 2470 PetscInt supportNew[2]; 2471 2472 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2473 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2474 /* Face A: {c, a, d} */ 2475 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2476 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2477 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2478 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2479 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 2480 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2481 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2482 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2483 #if 1 2484 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2485 for (p = 0; p < 3; ++p) { 2486 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 2487 } 2488 #endif 2489 supportNew[0] = (c - cStart)*8 + 0; 2490 supportNew[1] = (c - cStart)*8 + 0+4; 2491 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2492 #if 1 2493 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2494 for (p = 0; p < 2; ++p) { 2495 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); 2496 } 2497 #endif 2498 ++newp; 2499 /* Face B: {a, b, e} */ 2500 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2501 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2502 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 2503 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2504 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2505 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2506 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2507 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2508 #if 1 2509 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2510 for (p = 0; p < 3; ++p) { 2511 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); 2512 } 2513 #endif 2514 supportNew[0] = (c - cStart)*8 + 1; 2515 supportNew[1] = (c - cStart)*8 + 1+4; 2516 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2517 #if 1 2518 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2519 for (p = 0; p < 2; ++p) { 2520 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); 2521 } 2522 #endif 2523 ++newp; 2524 /* Face C: {c, f, b} */ 2525 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2526 orntNew[0] = ornt[2] < 0 ? -2 : 0; 2527 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2528 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2529 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 2530 orntNew[2] = ornt[0] < 0 ? -2 : 0; 2531 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2532 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2533 #if 1 2534 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2535 for (p = 0; p < 3; ++p) { 2536 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); 2537 } 2538 #endif 2539 supportNew[0] = (c - cStart)*8 + 2; 2540 supportNew[1] = (c - cStart)*8 + 2+4; 2541 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2542 #if 1 2543 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2544 for (p = 0; p < 2; ++p) { 2545 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 2546 } 2547 #endif 2548 ++newp; 2549 /* Face D: {d, e, f} */ 2550 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 2551 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2552 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2553 orntNew[1] = ornt[3] < 0 ? -2 : 0; 2554 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2555 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2556 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2557 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2558 #if 1 2559 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2560 for (p = 0; p < 3; ++p) { 2561 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); 2562 } 2563 #endif 2564 supportNew[0] = (c - cStart)*8 + 3; 2565 supportNew[1] = (c - cStart)*8 + 3+4; 2566 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2567 #if 1 2568 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2569 for (p = 0; p < 2; ++p) { 2570 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); 2571 } 2572 #endif 2573 ++newp; 2574 /* Face E: {d, f, a} */ 2575 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 2576 orntNew[0] = ornt[2] < 0 ? 0 : -2; 2577 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2578 orntNew[1] = -2; 2579 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 2580 orntNew[2] = ornt[1] < 0 ? -2 : 0; 2581 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2582 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2583 #if 1 2584 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2585 for (p = 0; p < 3; ++p) { 2586 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); 2587 } 2588 #endif 2589 supportNew[0] = (c - cStart)*8 + 0+4; 2590 supportNew[1] = (c - cStart)*8 + 3+4; 2591 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2592 #if 1 2593 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2594 for (p = 0; p < 2; ++p) { 2595 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); 2596 } 2597 #endif 2598 ++newp; 2599 /* Face F: {c, a, f} */ 2600 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 2601 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2602 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2603 orntNew[1] = 0; 2604 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 2605 orntNew[2] = ornt[2] < 0 ? 0 : -2; 2606 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2607 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2608 #if 1 2609 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2610 for (p = 0; p < 3; ++p) { 2611 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); 2612 } 2613 #endif 2614 supportNew[0] = (c - cStart)*8 + 0+4; 2615 supportNew[1] = (c - cStart)*8 + 2+4; 2616 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2617 #if 1 2618 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2619 for (p = 0; p < 2; ++p) { 2620 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); 2621 } 2622 #endif 2623 ++newp; 2624 /* Face G: {e, a, f} */ 2625 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 2626 orntNew[0] = ornt[1] < 0 ? -2 : 0; 2627 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2628 orntNew[1] = 0; 2629 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 2630 orntNew[2] = ornt[3] < 0 ? 0 : -2; 2631 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2632 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2633 #if 1 2634 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2635 for (p = 0; p < 3; ++p) { 2636 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); 2637 } 2638 #endif 2639 supportNew[0] = (c - cStart)*8 + 1+4; 2640 supportNew[1] = (c - cStart)*8 + 3+4; 2641 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2642 #if 1 2643 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2644 for (p = 0; p < 2; ++p) { 2645 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); 2646 } 2647 #endif 2648 ++newp; 2649 /* Face H: {a, b, f} */ 2650 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 2651 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2652 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 2653 orntNew[1] = ornt[3] < 0 ? 0 : -2; 2654 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2655 orntNew[2] = -2; 2656 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2657 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 2658 #if 1 2659 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2660 for (p = 0; p < 3; ++p) { 2661 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); 2662 } 2663 #endif 2664 supportNew[0] = (c - cStart)*8 + 1+4; 2665 supportNew[1] = (c - cStart)*8 + 2+4; 2666 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2667 #if 1 2668 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2669 for (p = 0; p < 2; ++p) { 2670 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); 2671 } 2672 #endif 2673 ++newp; 2674 } 2675 /* Split Edges have 2 vertices and the same faces as the parent */ 2676 for (e = eStart; e < eEnd; ++e) { 2677 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 2678 2679 for (r = 0; r < 2; ++r) { 2680 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 2681 const PetscInt *cone, *ornt, *support; 2682 PetscInt coneNew[2], coneSize, c, supportSize, s; 2683 2684 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 2685 coneNew[0] = vStartNew + (cone[0] - vStart); 2686 coneNew[1] = vStartNew + (cone[1] - vStart); 2687 coneNew[(r+1)%2] = newv; 2688 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2689 #if 1 2690 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2691 for (p = 0; p < 2; ++p) { 2692 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); 2693 } 2694 #endif 2695 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 2696 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2697 for (s = 0; s < supportSize; ++s) { 2698 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2699 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2700 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2701 for (c = 0; c < coneSize; ++c) { 2702 if (cone[c] == e) break; 2703 } 2704 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 2705 } 2706 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2707 #if 1 2708 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2709 for (p = 0; p < supportSize; ++p) { 2710 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); 2711 } 2712 #endif 2713 } 2714 } 2715 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 2716 for (f = fStart; f < fEnd; ++f) { 2717 const PetscInt *cone, *ornt, *support; 2718 PetscInt coneSize, supportSize, s; 2719 2720 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2721 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2722 for (r = 0; r < 3; ++r) { 2723 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 2724 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 2725 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 2726 -1, -1, 1, 6, 0, 4, 2727 2, 5, 3, 4, -1, -1, 2728 -1, -1, 3, 6, 2, 7}; 2729 2730 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2731 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 2732 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 2733 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2734 #if 1 2735 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2736 for (p = 0; p < 2; ++p) { 2737 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); 2738 } 2739 #endif 2740 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 2741 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 2742 for (s = 0; s < supportSize; ++s) { 2743 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2744 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2745 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2746 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 2747 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 2748 er = GetTetSomethingInverse_Static(ornt[c], r); 2749 if (er == eint[c]) { 2750 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 2751 } else { 2752 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 2753 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 2754 } 2755 } 2756 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2757 #if 1 2758 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2759 for (p = 0; p < intFaces; ++p) { 2760 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); 2761 } 2762 #endif 2763 } 2764 } 2765 /* Interior edges have 2 vertices and 4 faces */ 2766 for (c = cStart; c < cEnd; ++c) { 2767 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 2768 const PetscInt *cone, *ornt, *fcone; 2769 PetscInt coneNew[2], supportNew[4], find; 2770 2771 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2772 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2773 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 2774 find = GetTriEdge_Static(ornt[0], 0); 2775 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2776 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 2777 find = GetTriEdge_Static(ornt[2], 1); 2778 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 2779 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2780 #if 1 2781 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2782 for (p = 0; p < 2; ++p) { 2783 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); 2784 } 2785 #endif 2786 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2787 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2788 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2789 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2790 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2791 #if 1 2792 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 2793 for (p = 0; p < 4; ++p) { 2794 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); 2795 } 2796 #endif 2797 } 2798 /* Old vertices have identical supports */ 2799 for (v = vStart; v < vEnd; ++v) { 2800 const PetscInt newp = vStartNew + (v - vStart); 2801 const PetscInt *support, *cone; 2802 PetscInt size, s; 2803 2804 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2805 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2806 for (s = 0; s < size; ++s) { 2807 PetscInt r = 0; 2808 2809 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2810 if (cone[1] == v) r = 1; 2811 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 2812 } 2813 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2814 #if 1 2815 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2816 for (p = 0; p < size; ++p) { 2817 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); 2818 } 2819 #endif 2820 } 2821 /* Edge vertices have 2 + face*2 + 0/1 supports */ 2822 for (e = eStart; e < eEnd; ++e) { 2823 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 2824 const PetscInt *cone, *support; 2825 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 2826 2827 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 2828 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 2829 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 2830 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 2831 for (s = 0; s < size; ++s) { 2832 PetscInt r = 0; 2833 2834 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2835 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2836 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 2837 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 2838 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 2839 } 2840 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2841 for (s = 0; s < starSize*2; s += 2) { 2842 const PetscInt *cone, *ornt; 2843 PetscInt e01, e23; 2844 2845 if ((star[s] >= cStart) && (star[s] < cEnd)) { 2846 /* Check edge 0-1 */ 2847 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2848 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2849 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 2850 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 2851 /* Check edge 2-3 */ 2852 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 2853 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 2854 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 2855 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 2856 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 2857 } 2858 } 2859 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 2860 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2861 #if 1 2862 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2863 for (p = 0; p < 2+size*2+cellSize; ++p) { 2864 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); 2865 } 2866 #endif 2867 } 2868 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2869 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 2870 break; 2871 case REFINER_HYBRID_SIMPLEX_3D: 2872 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 2873 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2874 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2875 for (c = cStart; c < cMax; ++c) { 2876 const PetscInt newp = cStartNew + (c - cStart)*8; 2877 const PetscInt *cone, *ornt; 2878 PetscInt coneNew[4], orntNew[4]; 2879 2880 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2881 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2882 /* A tetrahedron: {0, a, c, d} */ 2883 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2884 orntNew[0] = ornt[0]; 2885 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2886 orntNew[1] = ornt[1]; 2887 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2888 orntNew[2] = ornt[2]; 2889 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2890 orntNew[3] = 0; 2891 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2892 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2893 #if 1 2894 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); 2895 for (p = 0; p < 4; ++p) { 2896 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); 2897 } 2898 #endif 2899 /* B tetrahedron: {a, 1, b, e} */ 2900 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2901 orntNew[0] = ornt[0]; 2902 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2903 orntNew[1] = ornt[1]; 2904 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2905 orntNew[2] = 0; 2906 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2907 orntNew[3] = ornt[3]; 2908 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2909 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2910 #if 1 2911 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); 2912 for (p = 0; p < 4; ++p) { 2913 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); 2914 } 2915 #endif 2916 /* C tetrahedron: {c, b, 2, f} */ 2917 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2918 orntNew[0] = ornt[0]; 2919 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2920 orntNew[1] = 0; 2921 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2922 orntNew[2] = ornt[2]; 2923 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2924 orntNew[3] = ornt[3]; 2925 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2926 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2927 #if 1 2928 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); 2929 for (p = 0; p < 4; ++p) { 2930 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); 2931 } 2932 #endif 2933 /* D tetrahedron: {d, e, f, 3} */ 2934 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 2935 orntNew[0] = 0; 2936 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2937 orntNew[1] = ornt[1]; 2938 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2939 orntNew[2] = ornt[2]; 2940 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2941 orntNew[3] = ornt[3]; 2942 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2943 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2944 #if 1 2945 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); 2946 for (p = 0; p < 4; ++p) { 2947 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); 2948 } 2949 #endif 2950 /* A' tetrahedron: {d, a, c, f} */ 2951 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 2952 orntNew[0] = -3; 2953 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2954 orntNew[1] = ornt[2] < 0 ? -(GetTetSomething_Static(ornt[2], 0)+1) : GetTetSomething_Static(ornt[2], 0); 2955 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2956 orntNew[2] = 0; 2957 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 2958 orntNew[3] = 2; 2959 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2960 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2961 #if 1 2962 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); 2963 for (p = 0; p < 4; ++p) { 2964 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); 2965 } 2966 #endif 2967 /* B' tetrahedron: {e, b, a, f} */ 2968 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 2969 orntNew[0] = -3; 2970 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 2971 orntNew[1] = 1; 2972 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2973 orntNew[2] = 0; 2974 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 2975 orntNew[3] = ornt[3] < 0 ? -(GetTetSomething_Static(ornt[3], 0)+1) : GetTetSomething_Static(ornt[3], 0); 2976 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2977 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2978 #if 1 2979 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); 2980 for (p = 0; p < 4; ++p) { 2981 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); 2982 } 2983 #endif 2984 /* C' tetrahedron: {b, f, c, a} */ 2985 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 2986 orntNew[0] = -3; 2987 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 2988 orntNew[1] = ornt[0] < 0 ? -(GetTetSomething_Static(ornt[0], 2)+1) : GetTetSomething_Static(ornt[0], 2); 2989 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 2990 orntNew[2] = -3; 2991 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 2992 orntNew[3] = -2; 2993 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2994 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2995 #if 1 2996 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); 2997 for (p = 0; p < 4; ++p) { 2998 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); 2999 } 3000 #endif 3001 /* D' tetrahedron: {f, e, d, a} */ 3002 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3003 orntNew[0] = -3; 3004 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3005 orntNew[1] = -3; 3006 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 3007 orntNew[2] = ornt[1] < 0 ? -(GetTetSomething_Static(ornt[1], 0)+1) : GetTetSomething_Static(ornt[1], 0); 3008 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3009 orntNew[3] = -3; 3010 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3011 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3012 #if 1 3013 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); 3014 for (p = 0; p < 4; ++p) { 3015 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); 3016 } 3017 #endif 3018 } 3019 /* Hybrid cells have 5 faces */ 3020 for (c = cMax; c < cEnd; ++c) { 3021 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 3022 const PetscInt *cone, *ornt, *fornt; 3023 PetscInt coneNew[5], orntNew[5], o, of, i; 3024 3025 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3026 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3027 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 3028 o = ornt[0] < 0 ? -1 : 1; 3029 for (r = 0; r < 3; ++r) { 3030 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 3031 orntNew[0] = ornt[0]; 3032 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 3033 orntNew[1] = ornt[1]; 3034 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 3035 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 3036 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 3037 orntNew[i] = 0; 3038 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 3039 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 3040 orntNew[i] = 0; 3041 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 3042 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 3043 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); 3044 orntNew[i] = 0; 3045 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3046 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3047 #if 1 3048 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); 3049 for (p = 0; p < 2; ++p) { 3050 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); 3051 } 3052 for (p = 2; p < 5; ++p) { 3053 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); 3054 } 3055 #endif 3056 } 3057 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 3058 orntNew[0] = 0; 3059 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3060 orntNew[1] = 0; 3061 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3062 orntNew[2] = 0; 3063 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3064 orntNew[3] = 0; 3065 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3066 orntNew[4] = 0; 3067 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3068 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3069 #if 1 3070 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); 3071 for (p = 0; p < 2; ++p) { 3072 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); 3073 } 3074 for (p = 2; p < 5; ++p) { 3075 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); 3076 } 3077 #endif 3078 } 3079 /* Split faces have 3 edges and the same cells as the parent */ 3080 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3081 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3082 for (f = fStart; f < fMax; ++f) { 3083 const PetscInt newp = fStartNew + (f - fStart)*4; 3084 const PetscInt *cone, *ornt, *support; 3085 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3086 3087 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3088 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3089 /* A triangle */ 3090 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3091 orntNew[0] = ornt[0]; 3092 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3093 orntNew[1] = -2; 3094 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3095 orntNew[2] = ornt[2]; 3096 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3097 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3098 #if 1 3099 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); 3100 for (p = 0; p < 3; ++p) { 3101 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); 3102 } 3103 #endif 3104 /* B triangle */ 3105 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3106 orntNew[0] = ornt[0]; 3107 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3108 orntNew[1] = ornt[1]; 3109 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3110 orntNew[2] = -2; 3111 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3112 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3113 #if 1 3114 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); 3115 for (p = 0; p < 3; ++p) { 3116 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); 3117 } 3118 #endif 3119 /* C triangle */ 3120 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3121 orntNew[0] = -2; 3122 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3123 orntNew[1] = ornt[1]; 3124 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3125 orntNew[2] = ornt[2]; 3126 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3127 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3128 #if 1 3129 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); 3130 for (p = 0; p < 3; ++p) { 3131 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); 3132 } 3133 #endif 3134 /* D triangle */ 3135 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3136 orntNew[0] = 0; 3137 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3138 orntNew[1] = 0; 3139 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3140 orntNew[2] = 0; 3141 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3142 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3143 #if 1 3144 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); 3145 for (p = 0; p < 3; ++p) { 3146 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); 3147 } 3148 #endif 3149 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3150 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3151 for (r = 0; r < 4; ++r) { 3152 for (s = 0; s < supportSize; ++s) { 3153 PetscInt subf; 3154 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3155 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3156 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3157 for (c = 0; c < coneSize; ++c) { 3158 if (cone[c] == f) break; 3159 } 3160 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3161 if (support[s] < cMax) { 3162 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3163 } else { 3164 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3165 } 3166 } 3167 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3168 #if 1 3169 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); 3170 for (p = 0; p < supportSize; ++p) { 3171 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); 3172 } 3173 #endif 3174 } 3175 } 3176 /* Interior cell faces have 3 edges and 2 cells */ 3177 for (c = cStart; c < cMax; ++c) { 3178 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3179 const PetscInt *cone, *ornt; 3180 PetscInt coneNew[3], orntNew[3]; 3181 PetscInt supportNew[2]; 3182 3183 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3184 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3185 /* Face A: {c, a, d} */ 3186 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3187 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3188 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3189 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3190 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 2); 3191 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3192 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3193 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3194 #if 1 3195 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3196 for (p = 0; p < 3; ++p) { 3197 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); 3198 } 3199 #endif 3200 supportNew[0] = (c - cStart)*8 + 0; 3201 supportNew[1] = (c - cStart)*8 + 0+4; 3202 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3203 #if 1 3204 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3205 for (p = 0; p < 2; ++p) { 3206 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); 3207 } 3208 #endif 3209 ++newp; 3210 /* Face B: {a, b, e} */ 3211 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3212 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3213 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 0); 3214 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3215 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3216 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3217 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3218 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3219 #if 1 3220 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); 3221 for (p = 0; p < 3; ++p) { 3222 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 3223 } 3224 #endif 3225 supportNew[0] = (c - cStart)*8 + 1; 3226 supportNew[1] = (c - cStart)*8 + 1+4; 3227 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3228 #if 1 3229 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3230 for (p = 0; p < 2; ++p) { 3231 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); 3232 } 3233 #endif 3234 ++newp; 3235 /* Face C: {c, f, b} */ 3236 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3237 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3238 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3239 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3240 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 1); 3241 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3242 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3243 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3244 #if 1 3245 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3246 for (p = 0; p < 3; ++p) { 3247 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); 3248 } 3249 #endif 3250 supportNew[0] = (c - cStart)*8 + 2; 3251 supportNew[1] = (c - cStart)*8 + 2+4; 3252 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3253 #if 1 3254 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3255 for (p = 0; p < 2; ++p) { 3256 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); 3257 } 3258 #endif 3259 ++newp; 3260 /* Face D: {d, e, f} */ 3261 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 0); 3262 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3263 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3264 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3265 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3266 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3267 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3268 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3269 #if 1 3270 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3271 for (p = 0; p < 3; ++p) { 3272 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); 3273 } 3274 #endif 3275 supportNew[0] = (c - cStart)*8 + 3; 3276 supportNew[1] = (c - cStart)*8 + 3+4; 3277 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3278 #if 1 3279 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3280 for (p = 0; p < 2; ++p) { 3281 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); 3282 } 3283 #endif 3284 ++newp; 3285 /* Face E: {d, f, a} */ 3286 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 1); 3287 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3288 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3289 orntNew[1] = -2; 3290 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 2); 3291 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3292 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3293 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3294 #if 1 3295 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3296 for (p = 0; p < 3; ++p) { 3297 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); 3298 } 3299 #endif 3300 supportNew[0] = (c - cStart)*8 + 0+4; 3301 supportNew[1] = (c - cStart)*8 + 3+4; 3302 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3303 #if 1 3304 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3305 for (p = 0; p < 2; ++p) { 3306 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); 3307 } 3308 #endif 3309 ++newp; 3310 /* Face F: {c, a, f} */ 3311 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 2); 3312 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3313 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3314 orntNew[1] = 0; 3315 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTetSomething_Static(ornt[2], 0); 3316 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3317 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3318 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3319 #if 1 3320 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3321 for (p = 0; p < 3; ++p) { 3322 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); 3323 } 3324 #endif 3325 supportNew[0] = (c - cStart)*8 + 0+4; 3326 supportNew[1] = (c - cStart)*8 + 2+4; 3327 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3328 #if 1 3329 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3330 for (p = 0; p < 2; ++p) { 3331 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); 3332 } 3333 #endif 3334 ++newp; 3335 /* Face G: {e, a, f} */ 3336 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTetSomething_Static(ornt[1], 1); 3337 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3338 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3339 orntNew[1] = 0; 3340 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 1); 3341 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3342 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3343 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3344 #if 1 3345 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3346 for (p = 0; p < 3; ++p) { 3347 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); 3348 } 3349 #endif 3350 supportNew[0] = (c - cStart)*8 + 1+4; 3351 supportNew[1] = (c - cStart)*8 + 3+4; 3352 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3353 #if 1 3354 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3355 for (p = 0; p < 2; ++p) { 3356 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); 3357 } 3358 #endif 3359 ++newp; 3360 /* Face H: {a, b, f} */ 3361 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTetSomething_Static(ornt[0], 0); 3362 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3363 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTetSomething_Static(ornt[3], 2); 3364 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3365 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3366 orntNew[2] = -2; 3367 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3368 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3369 #if 1 3370 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3371 for (p = 0; p < 3; ++p) { 3372 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); 3373 } 3374 #endif 3375 supportNew[0] = (c - cStart)*8 + 1+4; 3376 supportNew[1] = (c - cStart)*8 + 2+4; 3377 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3378 #if 1 3379 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3380 for (p = 0; p < 2; ++p) { 3381 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); 3382 } 3383 #endif 3384 ++newp; 3385 } 3386 /* Hybrid split faces have 4 edges and same cells */ 3387 for (f = fMax; f < fEnd; ++f) { 3388 const PetscInt *cone, *ornt, *support; 3389 PetscInt coneNew[4], orntNew[4]; 3390 PetscInt supportNew[2], size, s, c; 3391 3392 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3393 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3394 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3395 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3396 for (r = 0; r < 2; ++r) { 3397 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3398 3399 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3400 orntNew[0] = ornt[0]; 3401 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3402 orntNew[1] = ornt[1]; 3403 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3404 orntNew[2+r] = 0; 3405 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3406 orntNew[3-r] = 0; 3407 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3408 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3409 #if 1 3410 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3411 for (p = 0; p < 2; ++p) { 3412 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); 3413 } 3414 for (p = 2; p < 4; ++p) { 3415 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); 3416 } 3417 #endif 3418 for (s = 0; s < size; ++s) { 3419 const PetscInt *coneCell, *orntCell, *fornt; 3420 PetscInt o, of; 3421 3422 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3423 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3424 o = orntCell[0] < 0 ? -1 : 1; 3425 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3426 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3427 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3428 of = fornt[c-2] < 0 ? -1 : 1; 3429 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3430 } 3431 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3432 #if 1 3433 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3434 for (p = 0; p < size; ++p) { 3435 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); 3436 } 3437 #endif 3438 } 3439 } 3440 /* Hybrid cell faces have 4 edges and 2 cells */ 3441 for (c = cMax; c < cEnd; ++c) { 3442 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3443 const PetscInt *cone, *ornt; 3444 PetscInt coneNew[4], orntNew[4]; 3445 PetscInt supportNew[2]; 3446 3447 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3448 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3449 for (r = 0; r < 3; ++r) { 3450 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3451 orntNew[0] = 0; 3452 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3453 orntNew[1] = 0; 3454 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3455 orntNew[2] = 0; 3456 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3457 orntNew[3] = 0; 3458 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3459 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3460 #if 1 3461 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); 3462 for (p = 0; p < 2; ++p) { 3463 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); 3464 } 3465 for (p = 2; p < 4; ++p) { 3466 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); 3467 } 3468 #endif 3469 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3470 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3471 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3472 #if 1 3473 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); 3474 for (p = 0; p < 2; ++p) { 3475 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); 3476 } 3477 #endif 3478 } 3479 } 3480 /* Interior split edges have 2 vertices and the same faces as the parent */ 3481 for (e = eStart; e < eMax; ++e) { 3482 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3483 3484 for (r = 0; r < 2; ++r) { 3485 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3486 const PetscInt *cone, *ornt, *support; 3487 PetscInt coneNew[2], coneSize, c, supportSize, s; 3488 3489 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3490 coneNew[0] = vStartNew + (cone[0] - vStart); 3491 coneNew[1] = vStartNew + (cone[1] - vStart); 3492 coneNew[(r+1)%2] = newv; 3493 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3494 #if 1 3495 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3496 for (p = 0; p < 2; ++p) { 3497 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); 3498 } 3499 #endif 3500 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3501 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3502 for (s = 0; s < supportSize; ++s) { 3503 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3504 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3505 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3506 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 3507 if (support[s] < fMax) { 3508 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3509 } else { 3510 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 3511 } 3512 } 3513 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3514 #if 1 3515 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3516 for (p = 0; p < supportSize; ++p) { 3517 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); 3518 } 3519 #endif 3520 } 3521 } 3522 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 3523 for (f = fStart; f < fMax; ++f) { 3524 const PetscInt *cone, *ornt, *support; 3525 PetscInt coneSize, supportSize, s; 3526 3527 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3528 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3529 for (r = 0; r < 3; ++r) { 3530 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 3531 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3532 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3533 -1, -1, 1, 6, 0, 4, 3534 2, 5, 3, 4, -1, -1, 3535 -1, -1, 3, 6, 2, 7}; 3536 3537 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3538 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3539 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3540 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3541 #if 1 3542 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3543 for (p = 0; p < 2; ++p) { 3544 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); 3545 } 3546 #endif 3547 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3548 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3549 for (s = 0; s < supportSize; ++s) { 3550 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3551 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3552 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3553 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3554 if (support[s] < cMax) { 3555 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3556 er = GetTetSomethingInverse_Static(ornt[c], r); 3557 if (er == eint[c]) { 3558 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3559 } else { 3560 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3561 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3562 } 3563 } else { 3564 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 3565 } 3566 } 3567 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3568 #if 1 3569 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3570 for (p = 0; p < intFaces; ++p) { 3571 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); 3572 } 3573 #endif 3574 } 3575 } 3576 /* Interior cell edges have 2 vertices and 4 faces */ 3577 for (c = cStart; c < cMax; ++c) { 3578 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3579 const PetscInt *cone, *ornt, *fcone; 3580 PetscInt coneNew[2], supportNew[4], find; 3581 3582 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3583 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3584 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3585 find = GetTriEdge_Static(ornt[0], 0); 3586 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3587 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3588 find = GetTriEdge_Static(ornt[2], 1); 3589 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3590 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3591 #if 1 3592 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3593 for (p = 0; p < 2; ++p) { 3594 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); 3595 } 3596 #endif 3597 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3598 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3599 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3600 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3601 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3602 #if 1 3603 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 3604 for (p = 0; p < 4; ++p) { 3605 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); 3606 } 3607 #endif 3608 } 3609 /* Hybrid edges have two vertices and the same faces */ 3610 for (e = eMax; e < eEnd; ++e) { 3611 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 3612 const PetscInt *cone, *support, *fcone; 3613 PetscInt coneNew[2], size, fsize, s; 3614 3615 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3616 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3617 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3618 coneNew[0] = vStartNew + (cone[0] - vStart); 3619 coneNew[1] = vStartNew + (cone[1] - vStart); 3620 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3621 #if 1 3622 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3623 for (p = 0; p < 2; ++p) { 3624 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); 3625 } 3626 #endif 3627 for (s = 0; s < size; ++s) { 3628 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 3629 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 3630 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 3631 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 3632 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 3633 } 3634 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3635 #if 1 3636 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3637 for (p = 0; p < size; ++p) { 3638 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); 3639 } 3640 #endif 3641 } 3642 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 3643 for (f = fMax; f < fEnd; ++f) { 3644 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3645 const PetscInt *cone, *support, *ccone, *cornt; 3646 PetscInt coneNew[2], size, csize, s; 3647 3648 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3649 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3650 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3651 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 3652 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 3653 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3654 #if 1 3655 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3656 for (p = 0; p < 2; ++p) { 3657 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); 3658 } 3659 #endif 3660 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 3661 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 3662 for (s = 0; s < size; ++s) { 3663 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 3664 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 3665 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 3666 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 3667 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]); 3668 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 3669 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 3670 } 3671 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3672 #if 1 3673 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 3674 for (p = 0; p < 2+size*2; ++p) { 3675 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); 3676 } 3677 #endif 3678 } 3679 /* Interior vertices have identical supports */ 3680 for (v = vStart; v < vEnd; ++v) { 3681 const PetscInt newp = vStartNew + (v - vStart); 3682 const PetscInt *support, *cone; 3683 PetscInt size, s; 3684 3685 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3686 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3687 for (s = 0; s < size; ++s) { 3688 PetscInt r = 0; 3689 3690 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3691 if (cone[1] == v) r = 1; 3692 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3693 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 3694 } 3695 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3696 #if 1 3697 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3698 for (p = 0; p < size; ++p) { 3699 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); 3700 } 3701 #endif 3702 } 3703 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 3704 for (e = eStart; e < eMax; ++e) { 3705 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3706 const PetscInt *cone, *support; 3707 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 3708 3709 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3710 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3711 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3712 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3713 for (s = 0; s < size; ++s) { 3714 PetscInt r = 0; 3715 3716 if (support[s] < fMax) { 3717 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3718 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3719 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3720 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3721 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3722 faceSize += 2; 3723 } else { 3724 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 3725 ++faceSize; 3726 } 3727 } 3728 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3729 for (s = 0; s < starSize*2; s += 2) { 3730 const PetscInt *cone, *ornt; 3731 PetscInt e01, e23; 3732 3733 if ((star[s] >= cStart) && (star[s] < cMax)) { 3734 /* Check edge 0-1 */ 3735 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3736 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3737 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3738 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3739 /* Check edge 2-3 */ 3740 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3741 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3742 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3743 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3744 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 3745 } 3746 } 3747 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3748 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3749 #if 1 3750 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3751 for (p = 0; p < 2+faceSize+cellSize; ++p) { 3752 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); 3753 } 3754 #endif 3755 } 3756 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3757 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3758 break; 3759 case REFINER_HEX_3D: 3760 /* 3761 Bottom (viewed from top) Top 3762 1---------2---------2 7---------2---------6 3763 | | | | | | 3764 | B 2 C | | H 2 G | 3765 | | | | | | 3766 3----3----0----1----1 3----3----0----1----1 3767 | | | | | | 3768 | A 0 D | | E 0 F | 3769 | | | | | | 3770 0---------0---------3 4---------0---------5 3771 */ 3772 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 3773 for (c = cStart; c < cEnd; ++c) { 3774 const PetscInt newp = (c - cStart)*8; 3775 const PetscInt *cone, *ornt; 3776 PetscInt coneNew[6], orntNew[6]; 3777 3778 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3779 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3780 /* A hex */ 3781 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 3782 orntNew[0] = ornt[0]; 3783 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3784 orntNew[1] = 0; 3785 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 3786 orntNew[2] = ornt[2]; 3787 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3788 orntNew[3] = 0; 3789 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3790 orntNew[4] = 0; 3791 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 3792 orntNew[5] = ornt[5]; 3793 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3794 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3795 #if 1 3796 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); 3797 for (p = 0; p < 6; ++p) { 3798 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); 3799 } 3800 #endif 3801 /* B hex */ 3802 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 3803 orntNew[0] = ornt[0]; 3804 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3805 orntNew[1] = 0; 3806 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 3807 orntNew[2] = -1; 3808 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 3809 orntNew[3] = ornt[3]; 3810 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3811 orntNew[4] = 0; 3812 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 3813 orntNew[5] = ornt[5]; 3814 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3815 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3816 #if 1 3817 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); 3818 for (p = 0; p < 6; ++p) { 3819 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); 3820 } 3821 #endif 3822 /* C hex */ 3823 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 3824 orntNew[0] = ornt[0]; 3825 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3826 orntNew[1] = 0; 3827 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3828 orntNew[2] = -1; 3829 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 3830 orntNew[3] = ornt[3]; 3831 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 3832 orntNew[4] = ornt[4]; 3833 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 3834 orntNew[5] = -4; 3835 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3836 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3837 #if 1 3838 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); 3839 for (p = 0; p < 6; ++p) { 3840 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); 3841 } 3842 #endif 3843 /* D hex */ 3844 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 3845 orntNew[0] = ornt[0]; 3846 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3847 orntNew[1] = 0; 3848 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 3849 orntNew[2] = ornt[2]; 3850 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 3851 orntNew[3] = 0; 3852 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 3853 orntNew[4] = ornt[4]; 3854 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 3855 orntNew[5] = -4; 3856 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3857 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3858 #if 1 3859 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); 3860 for (p = 0; p < 6; ++p) { 3861 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); 3862 } 3863 #endif 3864 /* E hex */ 3865 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 3866 orntNew[0] = -4; 3867 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 3868 orntNew[1] = ornt[1]; 3869 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 3870 orntNew[2] = ornt[2]; 3871 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3872 orntNew[3] = 0; 3873 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3874 orntNew[4] = -1; 3875 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 3876 orntNew[5] = ornt[5]; 3877 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3878 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3879 #if 1 3880 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); 3881 for (p = 0; p < 6; ++p) { 3882 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); 3883 } 3884 #endif 3885 /* F hex */ 3886 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 3887 orntNew[0] = -4; 3888 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 3889 orntNew[1] = ornt[1]; 3890 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 3891 orntNew[2] = ornt[2]; 3892 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3893 orntNew[3] = -1; 3894 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 3895 orntNew[4] = ornt[4]; 3896 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 3897 orntNew[5] = 1; 3898 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3899 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3900 #if 1 3901 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); 3902 for (p = 0; p < 6; ++p) { 3903 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); 3904 } 3905 #endif 3906 /* G hex */ 3907 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 3908 orntNew[0] = -4; 3909 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 3910 orntNew[1] = ornt[1]; 3911 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 3912 orntNew[2] = 0; 3913 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 3914 orntNew[3] = ornt[3]; 3915 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 3916 orntNew[4] = ornt[4]; 3917 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3918 orntNew[5] = -3; 3919 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3920 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3921 #if 1 3922 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); 3923 for (p = 0; p < 6; ++p) { 3924 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); 3925 } 3926 #endif 3927 /* H hex */ 3928 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 3929 orntNew[0] = -4; 3930 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 3931 orntNew[1] = ornt[1]; 3932 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 3933 orntNew[2] = -1; 3934 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 3935 orntNew[3] = ornt[3]; 3936 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 3937 orntNew[4] = 3; 3938 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 3939 orntNew[5] = ornt[5]; 3940 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3941 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3942 #if 1 3943 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); 3944 for (p = 0; p < 6; ++p) { 3945 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); 3946 } 3947 #endif 3948 } 3949 /* Split faces have 4 edges and the same cells as the parent */ 3950 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3951 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3952 for (f = fStart; f < fEnd; ++f) { 3953 for (r = 0; r < 4; ++r) { 3954 /* TODO: This can come from GetFaces_Internal() */ 3955 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}; 3956 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 3957 const PetscInt *cone, *ornt, *support; 3958 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 3959 3960 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3961 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3962 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 3963 orntNew[(r+3)%4] = ornt[(r+3)%4]; 3964 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 3965 orntNew[(r+0)%4] = ornt[r]; 3966 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 3967 orntNew[(r+1)%4] = 0; 3968 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 3969 orntNew[(r+2)%4] = -2; 3970 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3971 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3972 #if 1 3973 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3974 for (p = 0; p < 4; ++p) { 3975 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); 3976 } 3977 #endif 3978 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3979 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3980 for (s = 0; s < supportSize; ++s) { 3981 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3982 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3983 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3984 for (c = 0; c < coneSize; ++c) { 3985 if (cone[c] == f) break; 3986 } 3987 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 3988 } 3989 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3990 #if 1 3991 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3992 for (p = 0; p < supportSize; ++p) { 3993 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); 3994 } 3995 #endif 3996 } 3997 } 3998 /* Interior faces have 4 edges and 2 cells */ 3999 for (c = cStart; c < cEnd; ++c) { 4000 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}; 4001 const PetscInt *cone, *ornt; 4002 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4003 4004 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4005 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4006 /* A-D face */ 4007 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 4008 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4009 orntNew[0] = 0; 4010 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4011 orntNew[1] = 0; 4012 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4013 orntNew[2] = -2; 4014 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4015 orntNew[3] = -2; 4016 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4017 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4018 #if 1 4019 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4020 for (p = 0; p < 4; ++p) { 4021 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); 4022 } 4023 #endif 4024 /* C-D face */ 4025 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 4026 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4027 orntNew[0] = 0; 4028 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4029 orntNew[1] = 0; 4030 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4031 orntNew[2] = -2; 4032 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4033 orntNew[3] = -2; 4034 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4035 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4036 #if 1 4037 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4038 for (p = 0; p < 4; ++p) { 4039 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); 4040 } 4041 #endif 4042 /* B-C face */ 4043 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 4044 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4045 orntNew[0] = -2; 4046 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4047 orntNew[1] = 0; 4048 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4049 orntNew[2] = 0; 4050 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4051 orntNew[3] = -2; 4052 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4053 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4054 #if 1 4055 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4056 for (p = 0; p < 4; ++p) { 4057 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); 4058 } 4059 #endif 4060 /* A-B face */ 4061 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 4062 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4063 orntNew[0] = -2; 4064 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4065 orntNew[1] = 0; 4066 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4067 orntNew[2] = 0; 4068 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 4069 orntNew[3] = -2; 4070 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4071 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4072 #if 1 4073 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4074 for (p = 0; p < 4; ++p) { 4075 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); 4076 } 4077 #endif 4078 /* E-F face */ 4079 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 4080 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4081 orntNew[0] = -2; 4082 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4083 orntNew[1] = -2; 4084 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4085 orntNew[2] = 0; 4086 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4087 orntNew[3] = 0; 4088 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4089 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4090 #if 1 4091 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4092 for (p = 0; p < 4; ++p) { 4093 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); 4094 } 4095 #endif 4096 /* F-G face */ 4097 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 4098 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4099 orntNew[0] = -2; 4100 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4101 orntNew[1] = -2; 4102 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4103 orntNew[2] = 0; 4104 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4105 orntNew[3] = 0; 4106 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4107 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4108 #if 1 4109 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4110 for (p = 0; p < 4; ++p) { 4111 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); 4112 } 4113 #endif 4114 /* G-H face */ 4115 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 4116 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4117 orntNew[0] = -2; 4118 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4119 orntNew[1] = 0; 4120 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4121 orntNew[2] = 0; 4122 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4123 orntNew[3] = -2; 4124 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4125 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4126 #if 1 4127 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4128 for (p = 0; p < 4; ++p) { 4129 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); 4130 } 4131 #endif 4132 /* E-H face */ 4133 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 4134 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4135 orntNew[0] = -2; 4136 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4137 orntNew[1] = -2; 4138 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4139 orntNew[2] = 0; 4140 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 4141 orntNew[3] = 0; 4142 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4143 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4144 #if 1 4145 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4146 for (p = 0; p < 4; ++p) { 4147 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); 4148 } 4149 #endif 4150 /* A-E face */ 4151 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 4152 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4153 orntNew[0] = 0; 4154 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4155 orntNew[1] = 0; 4156 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4157 orntNew[2] = -2; 4158 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4159 orntNew[3] = -2; 4160 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4161 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4162 #if 1 4163 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4164 for (p = 0; p < 4; ++p) { 4165 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); 4166 } 4167 #endif 4168 /* D-F face */ 4169 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 4170 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4171 orntNew[0] = -2; 4172 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4173 orntNew[1] = 0; 4174 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4175 orntNew[2] = 0; 4176 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 4177 orntNew[3] = -2; 4178 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4179 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4180 #if 1 4181 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4182 for (p = 0; p < 4; ++p) { 4183 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); 4184 } 4185 #endif 4186 /* C-G face */ 4187 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 4188 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 4189 orntNew[0] = -2; 4190 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4191 orntNew[1] = -2; 4192 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4193 orntNew[2] = 0; 4194 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4195 orntNew[3] = 0; 4196 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4197 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4198 #if 1 4199 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4200 for (p = 0; p < 4; ++p) { 4201 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); 4202 } 4203 #endif 4204 /* B-H face */ 4205 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 4206 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 4207 orntNew[0] = 0; 4208 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 4209 orntNew[1] = -2; 4210 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4211 orntNew[2] = -2; 4212 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4213 orntNew[3] = 0; 4214 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4215 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4216 #if 1 4217 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4218 for (p = 0; p < 4; ++p) { 4219 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); 4220 } 4221 #endif 4222 for (r = 0; r < 12; ++r) { 4223 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 4224 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4225 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4226 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4227 #if 1 4228 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4229 for (p = 0; p < 2; ++p) { 4230 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); 4231 } 4232 #endif 4233 } 4234 } 4235 /* Split edges have 2 vertices and the same faces as the parent */ 4236 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4237 for (e = eStart; e < eEnd; ++e) { 4238 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4239 4240 for (r = 0; r < 2; ++r) { 4241 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4242 const PetscInt *cone, *ornt, *support; 4243 PetscInt coneNew[2], coneSize, c, supportSize, s; 4244 4245 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4246 coneNew[0] = vStartNew + (cone[0] - vStart); 4247 coneNew[1] = vStartNew + (cone[1] - vStart); 4248 coneNew[(r+1)%2] = newv; 4249 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4250 #if 1 4251 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4252 for (p = 0; p < 2; ++p) { 4253 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); 4254 } 4255 #endif 4256 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4257 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4258 for (s = 0; s < supportSize; ++s) { 4259 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4260 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4261 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4262 for (c = 0; c < coneSize; ++c) { 4263 if (cone[c] == e) break; 4264 } 4265 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 4266 } 4267 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4268 #if 1 4269 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4270 for (p = 0; p < supportSize; ++p) { 4271 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); 4272 } 4273 #endif 4274 } 4275 } 4276 /* Face edges have 2 vertices and 2+cells faces */ 4277 for (f = fStart; f < fEnd; ++f) { 4278 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}; 4279 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4280 const PetscInt *cone, *coneCell, *orntCell, *support; 4281 PetscInt coneNew[2], coneSize, c, supportSize, s; 4282 4283 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4284 for (r = 0; r < 4; ++r) { 4285 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4286 4287 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4288 coneNew[1] = newv; 4289 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4290 #if 1 4291 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4292 for (p = 0; p < 2; ++p) { 4293 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); 4294 } 4295 #endif 4296 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4297 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4298 supportRef[0] = fStartNew + (f - fStart)*4 + r; 4299 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 4300 for (s = 0; s < supportSize; ++s) { 4301 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4302 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4303 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4304 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 4305 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 4306 } 4307 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4308 #if 1 4309 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4310 for (p = 0; p < 2+supportSize; ++p) { 4311 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); 4312 } 4313 #endif 4314 } 4315 } 4316 /* Cell edges have 2 vertices and 4 faces */ 4317 for (c = cStart; c < cEnd; ++c) { 4318 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}; 4319 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4320 const PetscInt *cone; 4321 PetscInt coneNew[2], supportNew[4]; 4322 4323 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4324 for (r = 0; r < 6; ++r) { 4325 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4326 4327 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4328 coneNew[1] = newv; 4329 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4330 #if 1 4331 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4332 for (p = 0; p < 2; ++p) { 4333 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); 4334 } 4335 #endif 4336 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 4337 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4338 #if 1 4339 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4340 for (p = 0; p < 4; ++p) { 4341 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); 4342 } 4343 #endif 4344 } 4345 } 4346 /* Old vertices have identical supports */ 4347 for (v = vStart; v < vEnd; ++v) { 4348 const PetscInt newp = vStartNew + (v - vStart); 4349 const PetscInt *support, *cone; 4350 PetscInt size, s; 4351 4352 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4353 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4354 for (s = 0; s < size; ++s) { 4355 PetscInt r = 0; 4356 4357 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4358 if (cone[1] == v) r = 1; 4359 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4360 } 4361 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4362 #if 1 4363 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4364 for (p = 0; p < size; ++p) { 4365 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); 4366 } 4367 #endif 4368 } 4369 /* Edge vertices have 2 + faces supports */ 4370 for (e = eStart; e < eEnd; ++e) { 4371 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4372 const PetscInt *cone, *support; 4373 PetscInt size, s; 4374 4375 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4376 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4377 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4378 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4379 for (s = 0; s < size; ++s) { 4380 PetscInt r; 4381 4382 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4383 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 4384 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 4385 } 4386 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4387 #if 1 4388 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4389 for (p = 0; p < 2+size; ++p) { 4390 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); 4391 } 4392 #endif 4393 } 4394 /* Face vertices have 4 + cells supports */ 4395 for (f = fStart; f < fEnd; ++f) { 4396 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4397 const PetscInt *cone, *support; 4398 PetscInt size, s; 4399 4400 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4401 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4402 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 4403 for (s = 0; s < size; ++s) { 4404 PetscInt r; 4405 4406 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4407 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 4408 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 4409 } 4410 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4411 #if 1 4412 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4413 for (p = 0; p < 4+size; ++p) { 4414 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); 4415 } 4416 #endif 4417 } 4418 /* Cell vertices have 6 supports */ 4419 for (c = cStart; c < cEnd; ++c) { 4420 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 4421 PetscInt supportNew[6]; 4422 4423 for (r = 0; r < 6; ++r) { 4424 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 4425 } 4426 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4427 } 4428 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4429 break; 4430 case REFINER_HYBRID_HEX_3D: 4431 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4432 /* 4433 Bottom (viewed from top) Top 4434 1---------2---------2 7---------2---------6 4435 | | | | | | 4436 | B 2 C | | H 2 G | 4437 | | | | | | 4438 3----3----0----1----1 3----3----0----1----1 4439 | | | | | | 4440 | A 0 D | | E 0 F | 4441 | | | | | | 4442 0---------0---------3 4---------0---------5 4443 */ 4444 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4445 for (c = cStart; c < cMax; ++c) { 4446 const PetscInt newp = (c - cStart)*8; 4447 const PetscInt *cone, *ornt; 4448 PetscInt coneNew[6], orntNew[6]; 4449 4450 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4451 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4452 /* A hex */ 4453 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4454 orntNew[0] = ornt[0]; 4455 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4456 orntNew[1] = 0; 4457 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4458 orntNew[2] = ornt[2]; 4459 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4460 orntNew[3] = 0; 4461 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4462 orntNew[4] = 0; 4463 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4464 orntNew[5] = ornt[5]; 4465 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4466 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4467 #if 1 4468 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); 4469 for (p = 0; p < 6; ++p) { 4470 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); 4471 } 4472 #endif 4473 /* B hex */ 4474 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4475 orntNew[0] = ornt[0]; 4476 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4477 orntNew[1] = 0; 4478 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4479 orntNew[2] = -1; 4480 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4481 orntNew[3] = ornt[3]; 4482 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4483 orntNew[4] = 0; 4484 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4485 orntNew[5] = ornt[5]; 4486 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4487 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4488 #if 1 4489 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); 4490 for (p = 0; p < 6; ++p) { 4491 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); 4492 } 4493 #endif 4494 /* C hex */ 4495 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4496 orntNew[0] = ornt[0]; 4497 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4498 orntNew[1] = 0; 4499 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4500 orntNew[2] = -1; 4501 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4502 orntNew[3] = ornt[3]; 4503 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4504 orntNew[4] = ornt[4]; 4505 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4506 orntNew[5] = -4; 4507 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4508 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4509 #if 1 4510 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); 4511 for (p = 0; p < 6; ++p) { 4512 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); 4513 } 4514 #endif 4515 /* D hex */ 4516 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4517 orntNew[0] = ornt[0]; 4518 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4519 orntNew[1] = 0; 4520 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4521 orntNew[2] = ornt[2]; 4522 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4523 orntNew[3] = 0; 4524 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4525 orntNew[4] = ornt[4]; 4526 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4527 orntNew[5] = -4; 4528 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4529 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4530 #if 1 4531 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); 4532 for (p = 0; p < 6; ++p) { 4533 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); 4534 } 4535 #endif 4536 /* E hex */ 4537 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4538 orntNew[0] = -4; 4539 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4540 orntNew[1] = ornt[1]; 4541 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4542 orntNew[2] = ornt[2]; 4543 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4544 orntNew[3] = 0; 4545 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4546 orntNew[4] = -1; 4547 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4548 orntNew[5] = ornt[5]; 4549 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4550 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4551 #if 1 4552 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); 4553 for (p = 0; p < 6; ++p) { 4554 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); 4555 } 4556 #endif 4557 /* F hex */ 4558 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4559 orntNew[0] = -4; 4560 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4561 orntNew[1] = ornt[1]; 4562 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4563 orntNew[2] = ornt[2]; 4564 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4565 orntNew[3] = -1; 4566 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4567 orntNew[4] = ornt[4]; 4568 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4569 orntNew[5] = 1; 4570 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4571 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4572 #if 1 4573 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); 4574 for (p = 0; p < 6; ++p) { 4575 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); 4576 } 4577 #endif 4578 /* G hex */ 4579 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4580 orntNew[0] = -4; 4581 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4582 orntNew[1] = ornt[1]; 4583 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4584 orntNew[2] = 0; 4585 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4586 orntNew[3] = ornt[3]; 4587 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4588 orntNew[4] = ornt[4]; 4589 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4590 orntNew[5] = -3; 4591 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4592 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4593 #if 1 4594 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); 4595 for (p = 0; p < 6; ++p) { 4596 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); 4597 } 4598 #endif 4599 /* H hex */ 4600 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4601 orntNew[0] = -4; 4602 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 4603 orntNew[1] = ornt[1]; 4604 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4605 orntNew[2] = -1; 4606 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 4607 orntNew[3] = ornt[3]; 4608 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 4609 orntNew[4] = 3; 4610 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 4611 orntNew[5] = ornt[5]; 4612 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4613 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4614 #if 1 4615 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); 4616 for (p = 0; p < 6; ++p) { 4617 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); 4618 } 4619 #endif 4620 } 4621 /* Hybrid cells have 6 faces: Front, Back, Sides */ 4622 /* 4623 3---------2---------2 4624 | | | 4625 | D 2 C | 4626 | | | 4627 3----3----0----1----1 4628 | | | 4629 | A 0 B | 4630 | | | 4631 0---------0---------1 4632 */ 4633 for (c = cMax; c < cEnd; ++c) { 4634 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 4635 const PetscInt *cone, *ornt, *fornt; 4636 PetscInt coneNew[6], orntNew[6], o, of, i; 4637 4638 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4639 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4640 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4641 o = ornt[0] < 0 ? -1 : 1; 4642 for (r = 0; r < 4; ++r) { 4643 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 4644 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 4645 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 4646 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]); 4647 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 4648 orntNew[0] = ornt[0]; 4649 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 4650 orntNew[1] = ornt[0]; 4651 of = fornt[edgeA] < 0 ? -1 : 1; 4652 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 4653 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 4654 orntNew[i] = ornt[edgeA]; 4655 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 4656 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 4657 orntNew[i] = 0; 4658 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 4659 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 4660 orntNew[i] = -2; 4661 of = fornt[edgeB] < 0 ? -1 : 1; 4662 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 4663 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 4664 orntNew[i] = ornt[edgeB]; 4665 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4666 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4667 #if 1 4668 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); 4669 for (p = 0; p < 2; ++p) { 4670 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); 4671 } 4672 for (p = 2; p < 6; ++p) { 4673 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); 4674 } 4675 #endif 4676 } 4677 } 4678 /* Interior split faces have 4 edges and the same cells as the parent */ 4679 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4680 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4681 for (f = fStart; f < fMax; ++f) { 4682 for (r = 0; r < 4; ++r) { 4683 /* TODO: This can come from GetFaces_Internal() */ 4684 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}; 4685 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 4686 const PetscInt *cone, *ornt, *support; 4687 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 4688 4689 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4690 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4691 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 4692 orntNew[(r+3)%4] = ornt[(r+3)%4]; 4693 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 4694 orntNew[(r+0)%4] = ornt[r]; 4695 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 4696 orntNew[(r+1)%4] = 0; 4697 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 4698 orntNew[(r+2)%4] = -2; 4699 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4700 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4701 #if 1 4702 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4703 for (p = 0; p < 4; ++p) { 4704 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); 4705 } 4706 #endif 4707 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4708 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4709 for (s = 0; s < supportSize; ++s) { 4710 PetscInt subf; 4711 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4712 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4713 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4714 for (c = 0; c < coneSize; ++c) { 4715 if (cone[c] == f) break; 4716 } 4717 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 4718 if (support[s] < cMax) { 4719 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 4720 } else { 4721 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 4722 } 4723 } 4724 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4725 #if 1 4726 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4727 for (p = 0; p < supportSize; ++p) { 4728 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); 4729 } 4730 #endif 4731 } 4732 } 4733 /* Interior cell faces have 4 edges and 2 cells */ 4734 for (c = cStart; c < cMax; ++c) { 4735 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}; 4736 const PetscInt *cone, *ornt; 4737 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 4738 4739 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4740 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4741 /* A-D face */ 4742 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 4743 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 4744 orntNew[0] = 0; 4745 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4746 orntNew[1] = 0; 4747 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4748 orntNew[2] = -2; 4749 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 4750 orntNew[3] = -2; 4751 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4752 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4753 #if 1 4754 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4755 for (p = 0; p < 4; ++p) { 4756 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); 4757 } 4758 #endif 4759 /* C-D face */ 4760 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 4761 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 4762 orntNew[0] = 0; 4763 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4764 orntNew[1] = 0; 4765 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4766 orntNew[2] = -2; 4767 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 4768 orntNew[3] = -2; 4769 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4770 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4771 #if 1 4772 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4773 for (p = 0; p < 4; ++p) { 4774 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); 4775 } 4776 #endif 4777 /* B-C face */ 4778 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 4779 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 4780 orntNew[0] = -2; 4781 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 4782 orntNew[1] = 0; 4783 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4784 orntNew[2] = 0; 4785 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4786 orntNew[3] = -2; 4787 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4788 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4789 #if 1 4790 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4791 for (p = 0; p < 4; ++p) { 4792 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); 4793 } 4794 #endif 4795 /* A-B face */ 4796 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 4797 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 4798 orntNew[0] = -2; 4799 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 4800 orntNew[1] = 0; 4801 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4802 orntNew[2] = 0; 4803 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 4804 orntNew[3] = -2; 4805 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4806 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4807 #if 1 4808 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4809 for (p = 0; p < 4; ++p) { 4810 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); 4811 } 4812 #endif 4813 /* E-F face */ 4814 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 4815 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4816 orntNew[0] = -2; 4817 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 4818 orntNew[1] = -2; 4819 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 4820 orntNew[2] = 0; 4821 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4822 orntNew[3] = 0; 4823 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4824 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4825 #if 1 4826 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4827 for (p = 0; p < 4; ++p) { 4828 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); 4829 } 4830 #endif 4831 /* F-G face */ 4832 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 4833 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4834 orntNew[0] = -2; 4835 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 4836 orntNew[1] = -2; 4837 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 4838 orntNew[2] = 0; 4839 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4840 orntNew[3] = 0; 4841 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4842 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4843 #if 1 4844 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4845 for (p = 0; p < 4; ++p) { 4846 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); 4847 } 4848 #endif 4849 /* G-H face */ 4850 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 4851 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 4852 orntNew[0] = -2; 4853 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 4854 orntNew[1] = 0; 4855 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4856 orntNew[2] = 0; 4857 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4858 orntNew[3] = -2; 4859 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4860 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4861 #if 1 4862 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4863 for (p = 0; p < 4; ++p) { 4864 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); 4865 } 4866 #endif 4867 /* E-H face */ 4868 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 4869 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4870 orntNew[0] = -2; 4871 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 4872 orntNew[1] = -2; 4873 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 4874 orntNew[2] = 0; 4875 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 4876 orntNew[3] = 0; 4877 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4878 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4879 #if 1 4880 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4881 for (p = 0; p < 4; ++p) { 4882 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); 4883 } 4884 #endif 4885 /* A-E face */ 4886 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 4887 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 4888 orntNew[0] = 0; 4889 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4890 orntNew[1] = 0; 4891 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4892 orntNew[2] = -2; 4893 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 4894 orntNew[3] = -2; 4895 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4896 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4897 #if 1 4898 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4899 for (p = 0; p < 4; ++p) { 4900 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); 4901 } 4902 #endif 4903 /* D-F face */ 4904 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 4905 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 4906 orntNew[0] = -2; 4907 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 4908 orntNew[1] = 0; 4909 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4910 orntNew[2] = 0; 4911 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 4912 orntNew[3] = -2; 4913 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4914 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4915 #if 1 4916 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4917 for (p = 0; p < 4; ++p) { 4918 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); 4919 } 4920 #endif 4921 /* C-G face */ 4922 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 4923 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 4924 orntNew[0] = -2; 4925 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 4926 orntNew[1] = -2; 4927 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 4928 orntNew[2] = 0; 4929 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4930 orntNew[3] = 0; 4931 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4932 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4933 #if 1 4934 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4935 for (p = 0; p < 4; ++p) { 4936 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); 4937 } 4938 #endif 4939 /* B-H face */ 4940 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 4941 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 4942 orntNew[0] = 0; 4943 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 4944 orntNew[1] = -2; 4945 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 4946 orntNew[2] = -2; 4947 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 4948 orntNew[3] = 0; 4949 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4950 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4951 #if 1 4952 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4953 for (p = 0; p < 4; ++p) { 4954 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); 4955 } 4956 #endif 4957 for (r = 0; r < 12; ++r) { 4958 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 4959 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 4960 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 4961 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4962 #if 1 4963 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4964 for (p = 0; p < 2; ++p) { 4965 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); 4966 } 4967 #endif 4968 } 4969 } 4970 /* Hybrid split faces have 4 edges and same cells */ 4971 for (f = fMax; f < fEnd; ++f) { 4972 const PetscInt *cone, *ornt, *support; 4973 PetscInt coneNew[4], orntNew[4]; 4974 PetscInt supportNew[2], size, s, c; 4975 4976 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4977 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4978 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4979 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4980 for (r = 0; r < 2; ++r) { 4981 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 4982 4983 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4984 orntNew[0] = ornt[0]; 4985 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4986 orntNew[1] = ornt[1]; 4987 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 4988 orntNew[2+r] = 0; 4989 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 4990 orntNew[3-r] = 0; 4991 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4992 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4993 #if 1 4994 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4995 for (p = 0; p < 2; ++p) { 4996 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); 4997 } 4998 for (p = 2; p < 4; ++p) { 4999 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); 5000 } 5001 #endif 5002 for (s = 0; s < size; ++s) { 5003 const PetscInt *coneCell, *orntCell, *fornt; 5004 PetscInt o, of; 5005 5006 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5007 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5008 o = orntCell[0] < 0 ? -1 : 1; 5009 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 5010 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 5011 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 5012 of = fornt[c-2] < 0 ? -1 : 1; 5013 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 5014 } 5015 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5016 #if 1 5017 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 5018 for (p = 0; p < size; ++p) { 5019 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); 5020 } 5021 #endif 5022 } 5023 } 5024 /* Hybrid cell faces have 4 edges and 2 cells */ 5025 for (c = cMax; c < cEnd; ++c) { 5026 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 5027 const PetscInt *cone, *ornt; 5028 PetscInt coneNew[4], orntNew[4]; 5029 PetscInt supportNew[2]; 5030 5031 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5032 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5033 for (r = 0; r < 4; ++r) { 5034 #if 0 5035 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 5036 orntNew[0] = 0; 5037 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 5038 orntNew[1] = 0; 5039 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 5040 orntNew[2] = 0; 5041 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5042 orntNew[3] = 0; 5043 #else 5044 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 5045 orntNew[0] = 0; 5046 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 5047 orntNew[1] = 0; 5048 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 5049 orntNew[2] = 0; 5050 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5051 orntNew[3] = 0; 5052 #endif 5053 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 5054 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 5055 #if 1 5056 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); 5057 for (p = 0; p < 2; ++p) { 5058 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); 5059 } 5060 for (p = 2; p < 4; ++p) { 5061 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); 5062 } 5063 #endif 5064 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 5065 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 5066 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 5067 #if 1 5068 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); 5069 for (p = 0; p < 2; ++p) { 5070 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); 5071 } 5072 #endif 5073 } 5074 } 5075 /* Interior split edges have 2 vertices and the same faces as the parent */ 5076 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5077 for (e = eStart; e < eMax; ++e) { 5078 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5079 5080 for (r = 0; r < 2; ++r) { 5081 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5082 const PetscInt *cone, *ornt, *support; 5083 PetscInt coneNew[2], coneSize, c, supportSize, s; 5084 5085 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5086 coneNew[0] = vStartNew + (cone[0] - vStart); 5087 coneNew[1] = vStartNew + (cone[1] - vStart); 5088 coneNew[(r+1)%2] = newv; 5089 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5090 #if 1 5091 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5092 for (p = 0; p < 2; ++p) { 5093 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); 5094 } 5095 #endif 5096 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5097 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5098 for (s = 0; s < supportSize; ++s) { 5099 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5100 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5101 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5102 for (c = 0; c < coneSize; ++c) { 5103 if (cone[c] == e) break; 5104 } 5105 if (support[s] < fMax) { 5106 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 5107 } else { 5108 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 5109 } 5110 } 5111 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5112 #if 1 5113 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5114 for (p = 0; p < supportSize; ++p) { 5115 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); 5116 } 5117 #endif 5118 } 5119 } 5120 /* Interior face edges have 2 vertices and 2+cells faces */ 5121 for (f = fStart; f < fMax; ++f) { 5122 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}; 5123 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5124 const PetscInt *cone, *coneCell, *orntCell, *support; 5125 PetscInt coneNew[2], coneSize, c, supportSize, s; 5126 5127 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5128 for (r = 0; r < 4; ++r) { 5129 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5130 5131 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5132 coneNew[1] = newv; 5133 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5134 #if 1 5135 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5136 for (p = 0; p < 2; ++p) { 5137 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); 5138 } 5139 #endif 5140 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5141 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5142 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5143 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5144 for (s = 0; s < supportSize; ++s) { 5145 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5146 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5147 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5148 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5149 if (support[s] < cMax) { 5150 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5151 } else { 5152 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 5153 } 5154 } 5155 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5156 #if 1 5157 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5158 for (p = 0; p < 2+supportSize; ++p) { 5159 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); 5160 } 5161 #endif 5162 } 5163 } 5164 /* Interior cell edges have 2 vertices and 4 faces */ 5165 for (c = cStart; c < cMax; ++c) { 5166 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}; 5167 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5168 const PetscInt *cone; 5169 PetscInt coneNew[2], supportNew[4]; 5170 5171 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5172 for (r = 0; r < 6; ++r) { 5173 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5174 5175 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 5176 coneNew[1] = newv; 5177 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5178 #if 1 5179 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5180 for (p = 0; p < 2; ++p) { 5181 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); 5182 } 5183 #endif 5184 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5185 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5186 #if 1 5187 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 5188 for (p = 0; p < 4; ++p) { 5189 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); 5190 } 5191 #endif 5192 } 5193 } 5194 /* Hybrid edges have two vertices and the same faces */ 5195 for (e = eMax; e < eEnd; ++e) { 5196 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 5197 const PetscInt *cone, *support, *fcone; 5198 PetscInt coneNew[2], size, fsize, s; 5199 5200 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5201 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5202 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5203 coneNew[0] = vStartNew + (cone[0] - vStart); 5204 coneNew[1] = vStartNew + (cone[1] - vStart); 5205 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5206 #if 1 5207 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5208 for (p = 0; p < 2; ++p) { 5209 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); 5210 } 5211 #endif 5212 for (s = 0; s < size; ++s) { 5213 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 5214 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 5215 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 5216 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 5217 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 5218 } 5219 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5220 #if 1 5221 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5222 for (p = 0; p < size; ++p) { 5223 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); 5224 } 5225 #endif 5226 } 5227 /* Hybrid face edges have 2 vertices and 2+cells faces */ 5228 for (f = fMax; f < fEnd; ++f) { 5229 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 5230 const PetscInt *cone, *support, *ccone, *cornt; 5231 PetscInt coneNew[2], size, csize, s; 5232 5233 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5234 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5235 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5236 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 5237 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 5238 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5239 #if 1 5240 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5241 for (p = 0; p < 2; ++p) { 5242 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); 5243 } 5244 #endif 5245 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 5246 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 5247 for (s = 0; s < size; ++s) { 5248 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 5249 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 5250 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 5251 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 5252 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]); 5253 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 5254 } 5255 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5256 #if 1 5257 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5258 for (p = 0; p < 2+size; ++p) { 5259 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); 5260 } 5261 #endif 5262 } 5263 /* Hybrid cell edges have 2 vertices and 4 faces */ 5264 for (c = cMax; c < cEnd; ++c) { 5265 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 5266 const PetscInt *cone, *support; 5267 PetscInt coneNew[2], size; 5268 5269 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5270 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 5271 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 5272 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 5273 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 5274 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5275 #if 1 5276 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5277 for (p = 0; p < 2; ++p) { 5278 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); 5279 } 5280 #endif 5281 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 5282 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 5283 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 5284 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 5285 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5286 #if 1 5287 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 5288 for (p = 0; p < 4; ++p) { 5289 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); 5290 } 5291 #endif 5292 } 5293 /* Interior vertices have identical supports */ 5294 for (v = vStart; v < vEnd; ++v) { 5295 const PetscInt newp = vStartNew + (v - vStart); 5296 const PetscInt *support, *cone; 5297 PetscInt size, s; 5298 5299 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5300 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5301 for (s = 0; s < size; ++s) { 5302 PetscInt r = 0; 5303 5304 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5305 if (cone[1] == v) r = 1; 5306 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5307 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 5308 } 5309 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5310 #if 1 5311 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5312 for (p = 0; p < size; ++p) { 5313 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); 5314 } 5315 #endif 5316 } 5317 /* Interior edge vertices have 2 + faces supports */ 5318 for (e = eStart; e < eMax; ++e) { 5319 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5320 const PetscInt *cone, *support; 5321 PetscInt size, s; 5322 5323 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5324 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5325 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5326 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5327 for (s = 0; s < size; ++s) { 5328 PetscInt r; 5329 5330 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5331 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5332 if (support[s] < fMax) { 5333 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 5334 } else { 5335 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 5336 } 5337 } 5338 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5339 #if 1 5340 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5341 for (p = 0; p < 2+size; ++p) { 5342 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); 5343 } 5344 #endif 5345 } 5346 /* Interior face vertices have 4 + cells supports */ 5347 for (f = fStart; f < fMax; ++f) { 5348 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5349 const PetscInt *cone, *support; 5350 PetscInt size, s; 5351 5352 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5353 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5354 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5355 for (s = 0; s < size; ++s) { 5356 PetscInt r; 5357 5358 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5359 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5360 if (support[s] < cMax) { 5361 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 5362 } else { 5363 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 5364 } 5365 } 5366 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5367 #if 1 5368 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5369 for (p = 0; p < 4+size; ++p) { 5370 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); 5371 } 5372 #endif 5373 } 5374 /* Cell vertices have 6 supports */ 5375 for (c = cStart; c < cMax; ++c) { 5376 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 5377 PetscInt supportNew[6]; 5378 5379 for (r = 0; r < 6; ++r) { 5380 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 5381 } 5382 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5383 } 5384 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5385 break; 5386 default: 5387 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5388 } 5389 PetscFunctionReturn(0); 5390 } 5391 5392 #undef __FUNCT__ 5393 #define __FUNCT__ "CellRefinerSetCoordinates" 5394 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5395 { 5396 PetscSection coordSection, coordSectionNew; 5397 Vec coordinates, coordinatesNew; 5398 PetscScalar *coords, *coordsNew; 5399 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 5400 PetscInt spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax, c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 5401 PetscErrorCode ierr; 5402 5403 PetscFunctionBegin; 5404 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5405 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5406 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5407 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5408 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5409 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 5410 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr);} 5411 ierr = GetDepthStart_Private(depth, depthSize, NULL, NULL, NULL, &vStartNew);CHKERRQ(ierr); 5412 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 5413 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 5414 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 5415 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 5416 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 5417 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 5418 if (cMax < 0) cMax = cEnd; 5419 if (fMax < 0) fMax = fEnd; 5420 if (eMax < 0) eMax = eEnd; 5421 /* All vertices have the spaceDim coordinates */ 5422 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 5423 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 5424 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 5425 } 5426 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 5427 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 5428 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 5429 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 5430 ierr = VecCreate(PetscObjectComm((PetscObject)dm), &coordinatesNew);CHKERRQ(ierr); 5431 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 5432 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 5433 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 5434 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 5435 ierr = VecSetFromOptions(coordinatesNew);CHKERRQ(ierr); 5436 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 5437 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5438 switch (refiner) { 5439 case REFINER_NOOP: break; 5440 case REFINER_HEX_3D: 5441 case REFINER_HYBRID_HEX_3D: 5442 /* Face vertices have the average of corner coordinates */ 5443 for (f = fStart; f < fMax; ++f) { 5444 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 5445 PetscInt *cone = NULL; 5446 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5447 5448 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5449 for (p = 0; p < closureSize*2; p += 2) { 5450 const PetscInt point = cone[p]; 5451 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5452 } 5453 for (v = 0; v < coneSize; ++v) { 5454 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5455 } 5456 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5457 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5458 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5459 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5460 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5461 } 5462 case REFINER_HEX_2D: 5463 case REFINER_HYBRID_HEX_2D: 5464 /* Cell vertices have the average of corner coordinates */ 5465 for (c = cStart; c < cMax; ++c) { 5466 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (c - cStart) + (spaceDim > 2 ? (fMax - fStart) : 0); 5467 PetscInt *cone = NULL; 5468 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 5469 5470 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5471 for (p = 0; p < closureSize*2; p += 2) { 5472 const PetscInt point = cone[p]; 5473 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 5474 } 5475 for (v = 0; v < coneSize; ++v) { 5476 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 5477 } 5478 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5479 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 5480 for (v = 0; v < coneSize; ++v) {ierr = DMPlexLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 5481 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 5482 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 5483 } 5484 case REFINER_SIMPLEX_2D: 5485 case REFINER_HYBRID_SIMPLEX_2D: 5486 case REFINER_SIMPLEX_3D: 5487 case REFINER_HYBRID_SIMPLEX_3D: 5488 /* Edge vertices have the average of endpoint coordinates */ 5489 for (e = eStart; e < eMax; ++e) { 5490 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5491 const PetscInt *cone; 5492 PetscInt coneSize, offA, offB, offnew, d; 5493 5494 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 5495 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 5496 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5497 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 5498 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 5499 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5500 ierr = DMPlexLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 5501 for (d = 0; d < spaceDim; ++d) { 5502 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 5503 } 5504 } 5505 /* Old vertices have the same coordinates */ 5506 for (v = vStart; v < vEnd; ++v) { 5507 const PetscInt newv = vStartNew + (v - vStart); 5508 PetscInt off, offnew, d; 5509 5510 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 5511 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 5512 for (d = 0; d < spaceDim; ++d) { 5513 coordsNew[offnew+d] = coords[off+d]; 5514 } 5515 } 5516 break; 5517 default: 5518 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5519 } 5520 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 5521 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 5522 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 5523 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 5524 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 5525 if (dm->maxCell) { 5526 const PetscReal *maxCell, *L; 5527 ierr = DMGetPeriodicity(dm, &maxCell, &L);CHKERRQ(ierr); 5528 ierr = DMSetPeriodicity(rdm, maxCell, L);CHKERRQ(ierr); 5529 } 5530 PetscFunctionReturn(0); 5531 } 5532 5533 #undef __FUNCT__ 5534 #define __FUNCT__ "DMPlexCreateProcessSF" 5535 /*@ 5536 DMPlexCreateProcessSF - Create an SF which just has process connectivity 5537 5538 Collective on DM 5539 5540 Input Parameters: 5541 + dm - The DM 5542 - sfPoint - The PetscSF which encodes point connectivity 5543 5544 Output Parameters: 5545 + processRanks - A list of process neighbors, or NULL 5546 - sfProcess - An SF encoding the process connectivity, or NULL 5547 5548 Level: developer 5549 5550 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 5551 @*/ 5552 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 5553 { 5554 PetscInt numRoots, numLeaves, l; 5555 const PetscInt *localPoints; 5556 const PetscSFNode *remotePoints; 5557 PetscInt *localPointsNew; 5558 PetscSFNode *remotePointsNew; 5559 PetscInt *ranks, *ranksNew; 5560 PetscMPIInt numProcs; 5561 PetscErrorCode ierr; 5562 5563 PetscFunctionBegin; 5564 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 5565 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 5566 if (processRanks) {PetscValidPointer(processRanks, 3);} 5567 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 5568 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &numProcs);CHKERRQ(ierr); 5569 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5570 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 5571 for (l = 0; l < numLeaves; ++l) { 5572 ranks[l] = remotePoints[l].rank; 5573 } 5574 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 5575 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 5576 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 5577 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 5578 for (l = 0; l < numLeaves; ++l) { 5579 ranksNew[l] = ranks[l]; 5580 localPointsNew[l] = l; 5581 remotePointsNew[l].index = 0; 5582 remotePointsNew[l].rank = ranksNew[l]; 5583 } 5584 ierr = PetscFree(ranks);CHKERRQ(ierr); 5585 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 5586 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 5587 if (sfProcess) { 5588 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 5589 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 5590 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 5591 ierr = PetscSFSetGraph(*sfProcess, numProcs, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 5592 } 5593 PetscFunctionReturn(0); 5594 } 5595 5596 #undef __FUNCT__ 5597 #define __FUNCT__ "CellRefinerCreateSF" 5598 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 5599 { 5600 PetscSF sf, sfNew, sfProcess; 5601 IS processRanks; 5602 MPI_Datatype depthType; 5603 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 5604 const PetscInt *localPoints, *neighbors; 5605 const PetscSFNode *remotePoints; 5606 PetscInt *localPointsNew; 5607 PetscSFNode *remotePointsNew; 5608 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 5609 PetscInt depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 5610 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 5611 PetscErrorCode ierr; 5612 5613 PetscFunctionBegin; 5614 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 5615 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 5616 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 5617 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 5618 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 5619 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 5620 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 5621 cMax = cMax < 0 ? cEnd : cMax; 5622 fMax = fMax < 0 ? fEnd : fMax; 5623 eMax = eMax < 0 ? eEnd : eMax; 5624 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 5625 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 5626 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 5627 /* Calculate size of new SF */ 5628 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 5629 if (numRoots < 0) PetscFunctionReturn(0); 5630 for (l = 0; l < numLeaves; ++l) { 5631 const PetscInt p = localPoints[l]; 5632 5633 switch (refiner) { 5634 case REFINER_SIMPLEX_2D: 5635 case REFINER_HYBRID_SIMPLEX_2D: 5636 if ((p >= vStart) && (p < vEnd)) { 5637 /* Interior vertices stay the same */ 5638 ++numLeavesNew; 5639 } else if ((p >= fStart) && (p < fMax)) { 5640 /* Interior faces add new faces and vertex */ 5641 numLeavesNew += 2 + 1; 5642 } else if ((p >= fMax) && (p < fEnd)) { 5643 /* Hybrid faces stay the same */ 5644 ++numLeavesNew; 5645 } else if ((p >= cStart) && (p < cMax)) { 5646 /* Interior cells add new cells and interior faces */ 5647 numLeavesNew += 4 + 3; 5648 } else if ((p >= cMax) && (p < cEnd)) { 5649 /* Hybrid cells add new cells and hybrid face */ 5650 numLeavesNew += 2 + 1; 5651 } 5652 break; 5653 case REFINER_HEX_2D: 5654 case REFINER_HYBRID_HEX_2D: 5655 if ((p >= vStart) && (p < vEnd)) { 5656 /* Interior vertices stay the same */ 5657 ++numLeavesNew; 5658 } else if ((p >= fStart) && (p < fMax)) { 5659 /* Interior faces add new faces and vertex */ 5660 numLeavesNew += 2 + 1; 5661 } else if ((p >= fMax) && (p < fEnd)) { 5662 /* Hybrid faces stay the same */ 5663 ++numLeavesNew; 5664 } else if ((p >= cStart) && (p < cMax)) { 5665 /* Interior cells add new cells, interior faces, and vertex */ 5666 numLeavesNew += 4 + 4 + 1; 5667 } else if ((p >= cMax) && (p < cEnd)) { 5668 /* Hybrid cells add new cells and hybrid face */ 5669 numLeavesNew += 2 + 1; 5670 } 5671 break; 5672 case REFINER_SIMPLEX_3D: 5673 case REFINER_HYBRID_SIMPLEX_3D: 5674 if ((p >= vStart) && (p < vEnd)) { 5675 /* Interior vertices stay the same */ 5676 ++numLeavesNew; 5677 } else if ((p >= eStart) && (p < eMax)) { 5678 /* Interior edges add new edges and vertex */ 5679 numLeavesNew += 2 + 1; 5680 } else if ((p >= eMax) && (p < eEnd)) { 5681 /* Hybrid edges stay the same */ 5682 ++numLeavesNew; 5683 } else if ((p >= fStart) && (p < fMax)) { 5684 /* Interior faces add new faces and edges */ 5685 numLeavesNew += 4 + 3; 5686 } else if ((p >= fMax) && (p < fEnd)) { 5687 /* Hybrid faces add new faces and edges */ 5688 numLeavesNew += 2 + 1; 5689 } else if ((p >= cStart) && (p < cMax)) { 5690 /* Interior cells add new cells, faces, and edges */ 5691 numLeavesNew += 8 + 8 + 1; 5692 } else if ((p >= cMax) && (p < cEnd)) { 5693 /* Hybrid cells add new cells and faces */ 5694 numLeavesNew += 4 + 3; 5695 } 5696 break; 5697 case REFINER_HEX_3D: 5698 case REFINER_HYBRID_HEX_3D: 5699 if ((p >= vStart) && (p < vEnd)) { 5700 /* Old vertices stay the same */ 5701 ++numLeavesNew; 5702 } else if ((p >= eStart) && (p < eMax)) { 5703 /* Interior edges add new edges, and vertex */ 5704 numLeavesNew += 2 + 1; 5705 } else if ((p >= eMax) && (p < eEnd)) { 5706 /* Hybrid edges stay the same */ 5707 ++numLeavesNew; 5708 } else if ((p >= fStart) && (p < fMax)) { 5709 /* Interior faces add new faces, edges, and vertex */ 5710 numLeavesNew += 4 + 4 + 1; 5711 } else if ((p >= fMax) && (p < fEnd)) { 5712 /* Hybrid faces add new faces and edges */ 5713 numLeavesNew += 2 + 1; 5714 } else if ((p >= cStart) && (p < cMax)) { 5715 /* Interior cells add new cells, faces, edges, and vertex */ 5716 numLeavesNew += 8 + 12 + 6 + 1; 5717 } else if ((p >= cStart) && (p < cEnd)) { 5718 /* Hybrid cells add new cells, faces, and edges */ 5719 numLeavesNew += 4 + 4 + 1; 5720 } 5721 break; 5722 default: 5723 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 5724 } 5725 } 5726 /* Communicate depthSizes for each remote rank */ 5727 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 5728 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 5729 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 5730 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 5731 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 5732 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 5733 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5734 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 5735 for (n = 0; n < numNeighbors; ++n) { 5736 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 5737 } 5738 depthSizeOld[depth] = cMax; 5739 depthSizeOld[0] = vMax; 5740 depthSizeOld[depth-1] = fMax; 5741 depthSizeOld[1] = eMax; 5742 5743 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5744 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 5745 5746 depthSizeOld[depth] = cEnd - cStart; 5747 depthSizeOld[0] = vEnd - vStart; 5748 depthSizeOld[depth-1] = fEnd - fStart; 5749 depthSizeOld[1] = eEnd - eStart; 5750 5751 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5752 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 5753 for (n = 0; n < numNeighbors; ++n) { 5754 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 5755 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 5756 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]; 5757 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 5758 } 5759 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 5760 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 5761 /* Calculate new point SF */ 5762 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 5763 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 5764 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 5765 for (l = 0, m = 0; l < numLeaves; ++l) { 5766 PetscInt p = localPoints[l]; 5767 PetscInt rp = remotePoints[l].index, n; 5768 PetscMPIInt rrank = remotePoints[l].rank; 5769 5770 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 5771 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 5772 switch (refiner) { 5773 case REFINER_SIMPLEX_2D: 5774 case REFINER_HYBRID_SIMPLEX_2D: 5775 if ((p >= vStart) && (p < vEnd)) { 5776 /* Old vertices stay the same */ 5777 localPointsNew[m] = vStartNew + (p - vStart); 5778 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5779 remotePointsNew[m].rank = rrank; 5780 ++m; 5781 } else if ((p >= fStart) && (p < fMax)) { 5782 /* Old interior faces add new faces and vertex */ 5783 for (r = 0; r < 2; ++r, ++m) { 5784 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5785 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5786 remotePointsNew[m].rank = rrank; 5787 } 5788 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5789 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5790 remotePointsNew[m].rank = rrank; 5791 ++m; 5792 } else if ((p >= fMax) && (p < fEnd)) { 5793 /* Old hybrid faces stay the same */ 5794 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5795 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5796 remotePointsNew[m].rank = rrank; 5797 ++m; 5798 } else if ((p >= cStart) && (p < cMax)) { 5799 /* Old interior cells add new cells and interior faces */ 5800 for (r = 0; r < 4; ++r, ++m) { 5801 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5802 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5803 remotePointsNew[m].rank = rrank; 5804 } 5805 for (r = 0; r < 3; ++r, ++m) { 5806 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 5807 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 5808 remotePointsNew[m].rank = rrank; 5809 } 5810 } else if ((p >= cMax) && (p < cEnd)) { 5811 /* Old hybrid cells add new cells and hybrid face */ 5812 for (r = 0; r < 2; ++r, ++m) { 5813 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5814 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5815 remotePointsNew[m].rank = rrank; 5816 } 5817 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 5818 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]); 5819 remotePointsNew[m].rank = rrank; 5820 ++m; 5821 } 5822 break; 5823 case REFINER_HEX_2D: 5824 case REFINER_HYBRID_HEX_2D: 5825 if ((p >= vStart) && (p < vEnd)) { 5826 /* Old vertices stay the same */ 5827 localPointsNew[m] = vStartNew + (p - vStart); 5828 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5829 remotePointsNew[m].rank = rrank; 5830 ++m; 5831 } else if ((p >= fStart) && (p < fMax)) { 5832 /* Old interior faces add new faces and vertex */ 5833 for (r = 0; r < 2; ++r, ++m) { 5834 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 5835 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 5836 remotePointsNew[m].rank = rrank; 5837 } 5838 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 5839 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 5840 remotePointsNew[m].rank = rrank; 5841 ++m; 5842 } else if ((p >= fMax) && (p < fEnd)) { 5843 /* Old hybrid faces stay the same */ 5844 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 5845 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 5846 remotePointsNew[m].rank = rrank; 5847 ++m; 5848 } else if ((p >= cStart) && (p < cMax)) { 5849 /* Old interior cells add new cells, interior faces, and vertex */ 5850 for (r = 0; r < 4; ++r, ++m) { 5851 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5852 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5853 remotePointsNew[m].rank = rrank; 5854 } 5855 for (r = 0; r < 4; ++r, ++m) { 5856 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 5857 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 5858 remotePointsNew[m].rank = rrank; 5859 } 5860 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 5861 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 5862 remotePointsNew[m].rank = rrank; 5863 ++m; 5864 } else if ((p >= cStart) && (p < cMax)) { 5865 /* Old hybrid cells add new cells and hybrid face */ 5866 for (r = 0; r < 2; ++r, ++m) { 5867 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 5868 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 5869 remotePointsNew[m].rank = rrank; 5870 } 5871 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 5872 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]); 5873 remotePointsNew[m].rank = rrank; 5874 ++m; 5875 } 5876 break; 5877 case REFINER_SIMPLEX_3D: 5878 case REFINER_HYBRID_SIMPLEX_3D: 5879 if ((p >= vStart) && (p < vEnd)) { 5880 /* Interior vertices stay the same */ 5881 localPointsNew[m] = vStartNew + (p - vStart); 5882 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5883 remotePointsNew[m].rank = rrank; 5884 ++m; 5885 } else if ((p >= eStart) && (p < eMax)) { 5886 /* Interior edges add new edges and vertex */ 5887 for (r = 0; r < 2; ++r, ++m) { 5888 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5889 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5890 remotePointsNew[m].rank = rrank; 5891 } 5892 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5893 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5894 remotePointsNew[m].rank = rrank; 5895 ++m; 5896 } else if ((p >= eMax) && (p < eEnd)) { 5897 /* Hybrid edges stay the same */ 5898 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 5899 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]); 5900 remotePointsNew[m].rank = rrank; 5901 ++m; 5902 } else if ((p >= fStart) && (p < fMax)) { 5903 /* Interior faces add new faces and edges */ 5904 for (r = 0; r < 4; ++r, ++m) { 5905 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5906 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5907 remotePointsNew[m].rank = rrank; 5908 } 5909 for (r = 0; r < 3; ++r, ++m) { 5910 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 5911 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 5912 remotePointsNew[m].rank = rrank; 5913 } 5914 } else if ((p >= fMax) && (p < fEnd)) { 5915 /* Hybrid faces add new faces and edges */ 5916 for (r = 0; r < 2; ++r, ++m) { 5917 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 5918 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; 5919 remotePointsNew[m].rank = rrank; 5920 } 5921 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 5922 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]); 5923 remotePointsNew[m].rank = rrank; 5924 ++m; 5925 } else if ((p >= cStart) && (p < cMax)) { 5926 /* Interior cells add new cells, faces, and edges */ 5927 for (r = 0; r < 8; ++r, ++m) { 5928 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 5929 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 5930 remotePointsNew[m].rank = rrank; 5931 } 5932 for (r = 0; r < 8; ++r, ++m) { 5933 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 5934 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 5935 remotePointsNew[m].rank = rrank; 5936 } 5937 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 5938 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; 5939 remotePointsNew[m].rank = rrank; 5940 ++m; 5941 } else if ((p >= cMax) && (p < cEnd)) { 5942 /* Hybrid cells add new cells and faces */ 5943 for (r = 0; r < 4; ++r, ++m) { 5944 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 5945 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 5946 remotePointsNew[m].rank = rrank; 5947 } 5948 for (r = 0; r < 3; ++r, ++m) { 5949 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 5950 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; 5951 remotePointsNew[m].rank = rrank; 5952 } 5953 } 5954 break; 5955 case REFINER_HEX_3D: 5956 case REFINER_HYBRID_HEX_3D: 5957 if ((p >= vStart) && (p < vEnd)) { 5958 /* Interior vertices stay the same */ 5959 localPointsNew[m] = vStartNew + (p - vStart); 5960 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 5961 remotePointsNew[m].rank = rrank; 5962 ++m; 5963 } else if ((p >= eStart) && (p < eMax)) { 5964 /* Interior edges add new edges and vertex */ 5965 for (r = 0; r < 2; ++r, ++m) { 5966 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 5967 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 5968 remotePointsNew[m].rank = rrank; 5969 } 5970 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 5971 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 5972 remotePointsNew[m].rank = rrank; 5973 ++m; 5974 } else if ((p >= eMax) && (p < eEnd)) { 5975 /* Hybrid edges stay the same */ 5976 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 5977 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]); 5978 remotePointsNew[m].rank = rrank; 5979 ++m; 5980 } else if ((p >= fStart) && (p < fMax)) { 5981 /* Interior faces add new faces, edges, and vertex */ 5982 for (r = 0; r < 4; ++r, ++m) { 5983 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 5984 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 5985 remotePointsNew[m].rank = rrank; 5986 } 5987 for (r = 0; r < 4; ++r, ++m) { 5988 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 5989 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 5990 remotePointsNew[m].rank = rrank; 5991 } 5992 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 5993 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 5994 remotePointsNew[m].rank = rrank; 5995 ++m; 5996 } else if ((p >= fMax) && (p < fEnd)) { 5997 /* Hybrid faces add new faces and edges */ 5998 for (r = 0; r < 2; ++r, ++m) { 5999 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6000 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; 6001 remotePointsNew[m].rank = rrank; 6002 } 6003 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 6004 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]); 6005 remotePointsNew[m].rank = rrank; 6006 ++m; 6007 } else if ((p >= cStart) && (p < cMax)) { 6008 /* Interior cells add new cells, faces, edges, and vertex */ 6009 for (r = 0; r < 8; ++r, ++m) { 6010 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 6011 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 6012 remotePointsNew[m].rank = rrank; 6013 } 6014 for (r = 0; r < 12; ++r, ++m) { 6015 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6016 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 6017 remotePointsNew[m].rank = rrank; 6018 } 6019 for (r = 0; r < 6; ++r, ++m) { 6020 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6021 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; 6022 remotePointsNew[m].rank = rrank; 6023 } 6024 for (r = 0; r < 1; ++r, ++m) { 6025 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 6026 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 6027 remotePointsNew[m].rank = rrank; 6028 } 6029 } else if ((p >= cMax) && (p < cEnd)) { 6030 /* Hybrid cells add new cells, faces, and edges */ 6031 for (r = 0; r < 4; ++r, ++m) { 6032 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6033 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 6034 remotePointsNew[m].rank = rrank; 6035 } 6036 for (r = 0; r < 4; ++r, ++m) { 6037 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6038 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; 6039 remotePointsNew[m].rank = rrank; 6040 } 6041 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 6042 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]); 6043 remotePointsNew[m].rank = rrank; 6044 ++m; 6045 } 6046 break; 6047 default: 6048 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6049 } 6050 } 6051 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 6052 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 6053 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 6054 { 6055 PetscSFNode *rp, *rtmp; 6056 PetscInt *lp, *idx, *ltmp, i; 6057 6058 /* SF needs sorted leaves to correct calculate Gather */ 6059 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 6060 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 6061 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 6062 for (i = 0; i < numLeavesNew; ++i) { 6063 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); 6064 idx[i] = i; 6065 } 6066 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 6067 for (i = 0; i < numLeavesNew; ++i) { 6068 lp[i] = localPointsNew[idx[i]]; 6069 rp[i] = remotePointsNew[idx[i]]; 6070 } 6071 ltmp = localPointsNew; 6072 localPointsNew = lp; 6073 rtmp = remotePointsNew; 6074 remotePointsNew = rp; 6075 ierr = PetscFree(idx);CHKERRQ(ierr); 6076 ierr = PetscFree(ltmp);CHKERRQ(ierr); 6077 ierr = PetscFree(rtmp);CHKERRQ(ierr); 6078 } 6079 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 6080 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 6081 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 6082 PetscFunctionReturn(0); 6083 } 6084 6085 #undef __FUNCT__ 6086 #define __FUNCT__ "CellRefinerCreateLabels" 6087 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6088 { 6089 PetscInt numLabels, l; 6090 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 6091 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6092 PetscErrorCode ierr; 6093 6094 PetscFunctionBegin; 6095 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6096 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6097 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6098 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6099 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6100 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6101 ierr = DMPlexGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 6102 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 6103 switch (refiner) { 6104 case REFINER_NOOP: 6105 case REFINER_SIMPLEX_2D: 6106 case REFINER_HEX_2D: 6107 case REFINER_SIMPLEX_3D: 6108 case REFINER_HEX_3D: 6109 break; 6110 case REFINER_HYBRID_SIMPLEX_3D: 6111 case REFINER_HYBRID_HEX_3D: 6112 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 6113 case REFINER_HYBRID_SIMPLEX_2D: 6114 case REFINER_HYBRID_HEX_2D: 6115 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 6116 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 6117 default: 6118 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6119 } 6120 for (l = 0; l < numLabels; ++l) { 6121 DMLabel label, labelNew; 6122 const char *lname; 6123 PetscBool isDepth; 6124 IS valueIS; 6125 const PetscInt *values; 6126 PetscInt numValues, val; 6127 6128 ierr = DMPlexGetLabelName(dm, l, &lname);CHKERRQ(ierr); 6129 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 6130 if (isDepth) continue; 6131 ierr = DMPlexCreateLabel(rdm, lname);CHKERRQ(ierr); 6132 ierr = DMPlexGetLabel(dm, lname, &label);CHKERRQ(ierr); 6133 ierr = DMPlexGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 6134 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 6135 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 6136 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 6137 for (val = 0; val < numValues; ++val) { 6138 IS pointIS; 6139 const PetscInt *points; 6140 PetscInt numPoints, n; 6141 6142 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 6143 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 6144 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 6145 /* Ensure refined label is created with same number of strata as 6146 * original (even if no entries here). */ 6147 if (!numPoints) { 6148 ierr = DMLabelSetValue(labelNew, 0, values[val]);CHKERRQ(ierr); 6149 ierr = DMLabelClearValue(labelNew, 0, values[val]);CHKERRQ(ierr); 6150 } 6151 for (n = 0; n < numPoints; ++n) { 6152 const PetscInt p = points[n]; 6153 switch (refiner) { 6154 case REFINER_SIMPLEX_2D: 6155 if ((p >= vStart) && (p < vEnd)) { 6156 /* Old vertices stay the same */ 6157 newp = vStartNew + (p - vStart); 6158 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6159 } else if ((p >= fStart) && (p < fEnd)) { 6160 /* Old faces add new faces and vertex */ 6161 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6162 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6163 for (r = 0; r < 2; ++r) { 6164 newp = fStartNew + (p - fStart)*2 + r; 6165 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6166 } 6167 } else if ((p >= cStart) && (p < cEnd)) { 6168 /* Old cells add new cells and interior faces */ 6169 for (r = 0; r < 4; ++r) { 6170 newp = cStartNew + (p - cStart)*4 + r; 6171 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6172 } 6173 for (r = 0; r < 3; ++r) { 6174 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6175 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6176 } 6177 } 6178 break; 6179 case REFINER_HEX_2D: 6180 if ((p >= vStart) && (p < vEnd)) { 6181 /* Old vertices stay the same */ 6182 newp = vStartNew + (p - vStart); 6183 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6184 } else if ((p >= fStart) && (p < fEnd)) { 6185 /* Old faces add new faces and vertex */ 6186 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6187 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6188 for (r = 0; r < 2; ++r) { 6189 newp = fStartNew + (p - fStart)*2 + r; 6190 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6191 } 6192 } else if ((p >= cStart) && (p < cEnd)) { 6193 /* Old cells add new cells and interior faces and vertex */ 6194 for (r = 0; r < 4; ++r) { 6195 newp = cStartNew + (p - cStart)*4 + r; 6196 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6197 } 6198 for (r = 0; r < 4; ++r) { 6199 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6200 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6201 } 6202 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6203 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6204 } 6205 break; 6206 case REFINER_HYBRID_SIMPLEX_2D: 6207 if ((p >= vStart) && (p < vEnd)) { 6208 /* Old vertices stay the same */ 6209 newp = vStartNew + (p - vStart); 6210 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6211 } else if ((p >= fStart) && (p < fMax)) { 6212 /* Old interior faces add new faces and vertex */ 6213 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6214 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6215 for (r = 0; r < 2; ++r) { 6216 newp = fStartNew + (p - fStart)*2 + r; 6217 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6218 } 6219 } else if ((p >= fMax) && (p < fEnd)) { 6220 /* Old hybrid faces stay the same */ 6221 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6222 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6223 } else if ((p >= cStart) && (p < cMax)) { 6224 /* Old interior cells add new cells and interior faces */ 6225 for (r = 0; r < 4; ++r) { 6226 newp = cStartNew + (p - cStart)*4 + r; 6227 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6228 } 6229 for (r = 0; r < 3; ++r) { 6230 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 6231 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6232 } 6233 } else if ((p >= cMax) && (p < cEnd)) { 6234 /* Old hybrid cells add new cells and hybrid face */ 6235 for (r = 0; r < 2; ++r) { 6236 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6237 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6238 } 6239 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 6240 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6241 } 6242 break; 6243 case REFINER_HYBRID_HEX_2D: 6244 if ((p >= vStart) && (p < vEnd)) { 6245 /* Old vertices stay the same */ 6246 newp = vStartNew + (p - vStart); 6247 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6248 } else if ((p >= fStart) && (p < fMax)) { 6249 /* Old interior faces add new faces and vertex */ 6250 newp = vStartNew + (vEnd - vStart) + (p - fStart); 6251 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6252 for (r = 0; r < 2; ++r) { 6253 newp = fStartNew + (p - fStart)*2 + r; 6254 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6255 } 6256 } else if ((p >= fMax) && (p < fEnd)) { 6257 /* Old hybrid faces stay the same */ 6258 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 6259 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6260 } else if ((p >= cStart) && (p < cMax)) { 6261 /* Old interior cells add new cells, interior faces, and vertex */ 6262 for (r = 0; r < 4; ++r) { 6263 newp = cStartNew + (p - cStart)*4 + r; 6264 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6265 } 6266 for (r = 0; r < 4; ++r) { 6267 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 6268 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6269 } 6270 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 6271 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6272 } else if ((p >= cMax) && (p < cEnd)) { 6273 /* Old hybrid cells add new cells and hybrid face */ 6274 for (r = 0; r < 2; ++r) { 6275 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 6276 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6277 } 6278 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 6279 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6280 } 6281 break; 6282 case REFINER_SIMPLEX_3D: 6283 if ((p >= vStart) && (p < vEnd)) { 6284 /* Old vertices stay the same */ 6285 newp = vStartNew + (p - vStart); 6286 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6287 } else if ((p >= eStart) && (p < eEnd)) { 6288 /* Old edges add new edges and vertex */ 6289 for (r = 0; r < 2; ++r) { 6290 newp = eStartNew + (p - eStart)*2 + r; 6291 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6292 } 6293 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6294 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6295 } else if ((p >= fStart) && (p < fEnd)) { 6296 /* Old faces add new faces and edges */ 6297 for (r = 0; r < 4; ++r) { 6298 newp = fStartNew + (p - fStart)*4 + r; 6299 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6300 } 6301 for (r = 0; r < 3; ++r) { 6302 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 6303 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6304 } 6305 } else if ((p >= cStart) && (p < cEnd)) { 6306 /* Old cells add new cells and interior faces and edges */ 6307 for (r = 0; r < 8; ++r) { 6308 newp = cStartNew + (p - cStart)*8 + r; 6309 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6310 } 6311 for (r = 0; r < 8; ++r) { 6312 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 6313 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6314 } 6315 for (r = 0; r < 1; ++r) { 6316 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 6317 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6318 } 6319 } 6320 break; 6321 case REFINER_HYBRID_SIMPLEX_3D: 6322 if ((p >= vStart) && (p < vEnd)) { 6323 /* Interior vertices stay the same */ 6324 newp = vStartNew + (p - vStart); 6325 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6326 } else if ((p >= eStart) && (p < eMax)) { 6327 /* Interior edges add new edges and vertex */ 6328 for (r = 0; r < 2; ++r) { 6329 newp = eStartNew + (p - eStart)*2 + r; 6330 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6331 } 6332 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6333 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6334 } else if ((p >= eMax) && (p < eEnd)) { 6335 /* Hybrid edges stay the same */ 6336 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 6337 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6338 } else if ((p >= fStart) && (p < fMax)) { 6339 /* Interior faces add new faces and edges */ 6340 for (r = 0; r < 4; ++r) { 6341 newp = fStartNew + (p - fStart)*4 + r; 6342 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6343 } 6344 for (r = 0; r < 3; ++r) { 6345 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 6346 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6347 } 6348 } else if ((p >= fMax) && (p < fEnd)) { 6349 /* Hybrid faces add new faces and edges */ 6350 for (r = 0; r < 2; ++r) { 6351 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 6352 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6353 } 6354 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 6355 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6356 } else if ((p >= cStart) && (p < cMax)) { 6357 /* Interior cells add new cells, faces, and edges */ 6358 for (r = 0; r < 8; ++r) { 6359 newp = cStartNew + (p - cStart)*8 + r; 6360 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6361 } 6362 for (r = 0; r < 8; ++r) { 6363 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 6364 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6365 } 6366 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 6367 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6368 } else if ((p >= cMax) && (p < cEnd)) { 6369 /* Hybrid cells add new cells and faces */ 6370 for (r = 0; r < 4; ++r) { 6371 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6372 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6373 } 6374 for (r = 0; r < 3; ++r) { 6375 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 6376 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6377 } 6378 } 6379 break; 6380 case REFINER_HEX_3D: 6381 if ((p >= vStart) && (p < vEnd)) { 6382 /* Old vertices stay the same */ 6383 newp = vStartNew + (p - vStart); 6384 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6385 } else if ((p >= eStart) && (p < eEnd)) { 6386 /* Old edges add new edges and vertex */ 6387 for (r = 0; r < 2; ++r) { 6388 newp = eStartNew + (p - eStart)*2 + r; 6389 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6390 } 6391 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6392 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6393 } else if ((p >= fStart) && (p < fEnd)) { 6394 /* Old faces add new faces, edges, and vertex */ 6395 for (r = 0; r < 4; ++r) { 6396 newp = fStartNew + (p - fStart)*4 + r; 6397 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6398 } 6399 for (r = 0; r < 4; ++r) { 6400 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 6401 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6402 } 6403 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 6404 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6405 } else if ((p >= cStart) && (p < cEnd)) { 6406 /* Old cells add new cells, faces, edges, and vertex */ 6407 for (r = 0; r < 8; ++r) { 6408 newp = cStartNew + (p - cStart)*8 + r; 6409 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6410 } 6411 for (r = 0; r < 12; ++r) { 6412 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 6413 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6414 } 6415 for (r = 0; r < 6; ++r) { 6416 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 6417 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6418 } 6419 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 6420 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6421 } 6422 break; 6423 case REFINER_HYBRID_HEX_3D: 6424 if ((p >= vStart) && (p < vEnd)) { 6425 /* Interior vertices stay the same */ 6426 newp = vStartNew + (p - vStart); 6427 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6428 } else if ((p >= eStart) && (p < eMax)) { 6429 /* Interior edges add new edges and vertex */ 6430 for (r = 0; r < 2; ++r) { 6431 newp = eStartNew + (p - eStart)*2 + r; 6432 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6433 } 6434 newp = vStartNew + (vEnd - vStart) + (p - eStart); 6435 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6436 } else if ((p >= eMax) && (p < eEnd)) { 6437 /* Hybrid edges stay the same */ 6438 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 6439 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6440 } else if ((p >= fStart) && (p < fMax)) { 6441 /* Interior faces add new faces, edges, and vertex */ 6442 for (r = 0; r < 4; ++r) { 6443 newp = fStartNew + (p - fStart)*4 + r; 6444 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6445 } 6446 for (r = 0; r < 4; ++r) { 6447 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 6448 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6449 } 6450 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 6451 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6452 } else if ((p >= fMax) && (p < fEnd)) { 6453 /* Hybrid faces add new faces and edges */ 6454 for (r = 0; r < 2; ++r) { 6455 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 6456 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6457 } 6458 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 6459 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6460 } else if ((p >= cStart) && (p < cMax)) { 6461 /* Interior cells add new cells, faces, edges, and vertex */ 6462 for (r = 0; r < 8; ++r) { 6463 newp = cStartNew + (p - cStart)*8 + r; 6464 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6465 } 6466 for (r = 0; r < 12; ++r) { 6467 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 6468 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6469 } 6470 for (r = 0; r < 6; ++r) { 6471 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 6472 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6473 } 6474 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 6475 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6476 } else if ((p >= cMax) && (p < cEnd)) { 6477 /* Hybrid cells add new cells, faces, and edges */ 6478 for (r = 0; r < 4; ++r) { 6479 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 6480 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6481 } 6482 for (r = 0; r < 4; ++r) { 6483 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 6484 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6485 } 6486 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 6487 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 6488 } 6489 break; 6490 default: 6491 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6492 } 6493 } 6494 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 6495 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 6496 } 6497 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 6498 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 6499 if (0) { 6500 ierr = PetscViewerASCIISynchronizedAllow(PETSC_VIEWER_STDOUT_WORLD, PETSC_TRUE);CHKERRQ(ierr); 6501 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6502 ierr = PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 6503 } 6504 } 6505 PetscFunctionReturn(0); 6506 } 6507 6508 #undef __FUNCT__ 6509 #define __FUNCT__ "DMPlexRefineUniform_Internal" 6510 /* This will only work for interpolated meshes */ 6511 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 6512 { 6513 DM rdm; 6514 PetscInt *depthSize; 6515 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 6516 PetscErrorCode ierr; 6517 6518 PetscFunctionBegin; 6519 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 6520 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 6521 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6522 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 6523 /* Calculate number of new points of each depth */ 6524 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6525 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 6526 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 6527 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6528 /* Step 1: Set chart */ 6529 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 6530 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 6531 /* Step 2: Set cone/support sizes */ 6532 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6533 /* Step 3: Setup refined DM */ 6534 ierr = DMSetUp(rdm);CHKERRQ(ierr); 6535 /* Step 4: Set cones and supports */ 6536 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6537 /* Step 5: Stratify */ 6538 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 6539 /* Step 6: Create pointSF */ 6540 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6541 /* Step 7: Set coordinates for vertices */ 6542 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6543 /* Step 8: Create labels */ 6544 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 6545 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6546 6547 *dmRefined = rdm; 6548 PetscFunctionReturn(0); 6549 } 6550 6551 #undef __FUNCT__ 6552 #define __FUNCT__ "DMPlexCreateCoarsePointIS" 6553 /*@ 6554 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 6555 6556 Input Parameter: 6557 . dm - The coarse DM 6558 6559 Output Parameter: 6560 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 6561 6562 Level: developer 6563 6564 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 6565 @*/ 6566 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 6567 { 6568 CellRefiner cellRefiner; 6569 PetscInt *depthSize, *fpoints; 6570 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 6571 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 6572 PetscErrorCode ierr; 6573 6574 PetscFunctionBegin; 6575 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6576 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 6577 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6578 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 6579 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 6580 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 6581 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 6582 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 6583 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 6584 switch (cellRefiner) { 6585 case 1: /* Simplicial 2D */ 6586 case 3: /* Hybrid simplicial 2D */ 6587 case 2: /* Hex 2D */ 6588 case 4: /* Hybrid Hex 2D */ 6589 case 5: /* Simplicial 3D */ 6590 case 7: /* Hybrid Simplicial 3D */ 6591 case 6: /* Hex 3D */ 6592 case 8: /* Hybrid Hex 3D */ 6593 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 6594 break; 6595 default: 6596 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 6597 } 6598 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 6599 ierr = PetscFree(depthSize);CHKERRQ(ierr); 6600 PetscFunctionReturn(0); 6601 } 6602 6603 #undef __FUNCT__ 6604 #define __FUNCT__ "DMPlexSetRefinementUniform" 6605 /*@ 6606 DMPlexSetRefinementUniform - Set the flag for uniform refinement 6607 6608 Input Parameters: 6609 + dm - The DM 6610 - refinementUniform - The flag for uniform refinement 6611 6612 Level: developer 6613 6614 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6615 @*/ 6616 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 6617 { 6618 DM_Plex *mesh = (DM_Plex*) dm->data; 6619 6620 PetscFunctionBegin; 6621 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6622 mesh->refinementUniform = refinementUniform; 6623 PetscFunctionReturn(0); 6624 } 6625 6626 #undef __FUNCT__ 6627 #define __FUNCT__ "DMPlexGetRefinementUniform" 6628 /*@ 6629 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 6630 6631 Input Parameter: 6632 . dm - The DM 6633 6634 Output Parameter: 6635 . refinementUniform - The flag for uniform refinement 6636 6637 Level: developer 6638 6639 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 6640 @*/ 6641 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 6642 { 6643 DM_Plex *mesh = (DM_Plex*) dm->data; 6644 6645 PetscFunctionBegin; 6646 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6647 PetscValidPointer(refinementUniform, 2); 6648 *refinementUniform = mesh->refinementUniform; 6649 PetscFunctionReturn(0); 6650 } 6651 6652 #undef __FUNCT__ 6653 #define __FUNCT__ "DMPlexSetRefinementLimit" 6654 /*@ 6655 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 6656 6657 Input Parameters: 6658 + dm - The DM 6659 - refinementLimit - The maximum cell volume in the refined mesh 6660 6661 Level: developer 6662 6663 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6664 @*/ 6665 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 6666 { 6667 DM_Plex *mesh = (DM_Plex*) dm->data; 6668 6669 PetscFunctionBegin; 6670 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6671 mesh->refinementLimit = refinementLimit; 6672 PetscFunctionReturn(0); 6673 } 6674 6675 #undef __FUNCT__ 6676 #define __FUNCT__ "DMPlexGetRefinementLimit" 6677 /*@ 6678 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 6679 6680 Input Parameter: 6681 . dm - The DM 6682 6683 Output Parameter: 6684 . refinementLimit - The maximum cell volume in the refined mesh 6685 6686 Level: developer 6687 6688 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 6689 @*/ 6690 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 6691 { 6692 DM_Plex *mesh = (DM_Plex*) dm->data; 6693 6694 PetscFunctionBegin; 6695 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 6696 PetscValidPointer(refinementLimit, 2); 6697 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 6698 *refinementLimit = mesh->refinementLimit; 6699 PetscFunctionReturn(0); 6700 } 6701 6702 #undef __FUNCT__ 6703 #define __FUNCT__ "DMPlexGetCellRefiner_Internal" 6704 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 6705 { 6706 PetscInt dim, cStart, cEnd, coneSize, cMax; 6707 PetscErrorCode ierr; 6708 6709 PetscFunctionBegin; 6710 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6711 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6712 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 6713 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 6714 ierr = DMPlexGetHybridBounds(dm, &cMax, NULL, NULL, NULL);CHKERRQ(ierr); 6715 switch (dim) { 6716 case 2: 6717 switch (coneSize) { 6718 case 3: 6719 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 6720 else *cellRefiner = REFINER_SIMPLEX_2D; 6721 break; 6722 case 4: 6723 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 6724 else *cellRefiner = REFINER_HEX_2D; 6725 break; 6726 default: 6727 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6728 } 6729 break; 6730 case 3: 6731 switch (coneSize) { 6732 case 4: 6733 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 6734 else *cellRefiner = REFINER_SIMPLEX_3D; 6735 break; 6736 case 6: 6737 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 6738 else *cellRefiner = REFINER_HEX_3D; 6739 break; 6740 default: 6741 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 6742 } 6743 break; 6744 default: 6745 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 6746 } 6747 PetscFunctionReturn(0); 6748 } 6749