1 #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2 #include <petscsf.h> 3 4 PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 5 { 6 PetscFunctionBegin; 7 if (cStart) *cStart = 0; 8 if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth]; 9 if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 10 if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 11 PetscFunctionReturn(0); 12 } 13 14 PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 15 { 16 PetscFunctionBegin; 17 if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth]; 18 if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 19 if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 20 if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 21 PetscFunctionReturn(0); 22 } 23 24 /* Gets the affine map from the original cell to each subcell */ 25 PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 26 { 27 PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ; 28 PetscInt dim, s; 29 PetscErrorCode ierr; 30 31 PetscFunctionBegin; 32 switch (refiner) { 33 case REFINER_NOOP: break; 34 case REFINER_SIMPLEX_2D: 35 /* 36 2 37 |\ 38 | \ 39 | \ 40 | \ 41 | C \ 42 | \ 43 | \ 44 2---1---1 45 |\ D / \ 46 | 2 0 \ 47 |A \ / B \ 48 0---0-------1 49 */ 50 dim = 2; 51 if (numSubcells) *numSubcells = 4; 52 if (v0) { 53 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 54 /* A */ 55 v[0+0] = -1.0; v[0+1] = -1.0; 56 j[0+0] = 0.5; j[0+1] = 0.0; 57 j[0+2] = 0.0; j[0+3] = 0.5; 58 /* B */ 59 v[2+0] = 0.0; v[2+1] = -1.0; 60 j[4+0] = 0.5; j[4+1] = 0.0; 61 j[4+2] = 0.0; j[4+3] = 0.5; 62 /* C */ 63 v[4+0] = -1.0; v[4+1] = 0.0; 64 j[8+0] = 0.5; j[8+1] = 0.0; 65 j[8+2] = 0.0; j[8+3] = 0.5; 66 /* D */ 67 v[6+0] = 0.0; v[6+1] = -1.0; 68 j[12+0] = 0.0; j[12+1] = -0.5; 69 j[12+2] = 0.5; j[12+3] = 0.5; 70 for (s = 0; s < 4; ++s) { 71 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 72 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 73 } 74 } 75 break; 76 case REFINER_HEX_2D: 77 /* 78 3---------2---------2 79 | | | 80 | D 2 C | 81 | | | 82 3----3----0----1----1 83 | | | 84 | A 0 B | 85 | | | 86 0---------0---------1 87 */ 88 dim = 2; 89 if (numSubcells) *numSubcells = 4; 90 if (v0) { 91 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 92 /* A */ 93 v[0+0] = -1.0; v[0+1] = -1.0; 94 j[0+0] = 0.5; j[0+1] = 0.0; 95 j[0+2] = 0.0; j[0+3] = 0.5; 96 /* B */ 97 v[2+0] = 0.0; v[2+1] = -1.0; 98 j[4+0] = 0.5; j[4+1] = 0.0; 99 j[4+2] = 0.0; j[4+3] = 0.5; 100 /* C */ 101 v[4+0] = 0.0; v[4+1] = 0.0; 102 j[8+0] = 0.5; j[8+1] = 0.0; 103 j[8+2] = 0.0; j[8+3] = 0.5; 104 /* D */ 105 v[6+0] = -1.0; v[6+1] = 0.0; 106 j[12+0] = 0.5; j[12+1] = 0.0; 107 j[12+2] = 0.0; j[12+3] = 0.5; 108 for (s = 0; s < 4; ++s) { 109 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 110 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 111 } 112 } 113 break; 114 case REFINER_HEX_3D: 115 /* 116 Bottom (viewed from top) Top 117 1---------2---------2 7---------2---------6 118 | | | | | | 119 | B 2 C | | H 2 G | 120 | | | | | | 121 3----3----0----1----1 3----3----0----1----1 122 | | | | | | 123 | A 0 D | | E 0 F | 124 | | | | | | 125 0---------0---------3 4---------0---------5 126 */ 127 break; 128 dim = 3; 129 if (numSubcells) *numSubcells = 8; 130 if (v0) { 131 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 132 /* A */ 133 v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0; 134 j[0+0] = 0.5; j[0+1] = 0.0; j[0+2] = 0.0; 135 j[0+3] = 0.0; j[0+4] = 0.5; j[0+5] = 0.0; 136 j[0+6] = 0.0; j[0+7] = 0.0; j[0+8] = 0.5; 137 /* B */ 138 v[3+0] = -1.0; v[3+1] = 0.0; v[3+2] = -1.0; 139 j[9+0] = 0.5; j[9+1] = 0.0; j[9+2] = 0.0; 140 j[9+3] = 0.0; j[9+4] = 0.5; j[9+5] = 0.0; 141 j[9+6] = 0.0; j[9+7] = 0.0; j[9+8] = 0.5; 142 /* C */ 143 v[6+0] = 0.0; v[6+1] = 0.0; v[6+2] = -1.0; 144 j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0; 145 j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0; 146 j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5; 147 /* D */ 148 v[9+0] = 0.0; v[9+1] = -1.0; v[9+2] = -1.0; 149 j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0; 150 j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0; 151 j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5; 152 /* E */ 153 v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] = 0.0; 154 j[36+0] = 0.5; j[36+1] = 0.0; j[36+2] = 0.0; 155 j[36+3] = 0.0; j[36+4] = 0.5; j[36+5] = 0.0; 156 j[36+6] = 0.0; j[36+7] = 0.0; j[36+8] = 0.5; 157 /* F */ 158 v[15+0] = 0.0; v[15+1] = -1.0; v[15+2] = 0.0; 159 j[45+0] = 0.5; j[45+1] = 0.0; j[45+2] = 0.0; 160 j[45+3] = 0.0; j[45+4] = 0.5; j[45+5] = 0.0; 161 j[45+6] = 0.0; j[45+7] = 0.0; j[45+8] = 0.5; 162 /* G */ 163 v[18+0] = 0.0; v[18+1] = 0.0; v[18+2] = 0.0; 164 j[54+0] = 0.5; j[54+1] = 0.0; j[54+2] = 0.0; 165 j[54+3] = 0.0; j[54+4] = 0.5; j[54+5] = 0.0; 166 j[54+6] = 0.0; j[54+7] = 0.0; j[54+8] = 0.5; 167 /* H */ 168 v[21+0] = -1.0; v[21+1] = 0.0; v[21+2] = 0.0; 169 j[63+0] = 0.5; j[63+1] = 0.0; j[63+2] = 0.0; 170 j[63+3] = 0.0; j[63+4] = 0.5; j[63+5] = 0.0; 171 j[63+6] = 0.0; j[63+7] = 0.0; j[63+8] = 0.5; 172 for (s = 0; s < 8; ++s) { 173 DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]); 174 DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 175 } 176 } 177 default: 178 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 179 } 180 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 181 PetscFunctionReturn(0); 182 } 183 184 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 185 { 186 PetscErrorCode ierr; 187 188 PetscFunctionBegin; 189 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 190 PetscFunctionReturn(0); 191 } 192 193 /* Should this be here or in the DualSpace somehow? */ 194 PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside) 195 { 196 PetscReal sum = 0.0; 197 PetscInt d; 198 199 PetscFunctionBegin; 200 *inside = PETSC_TRUE; 201 switch (refiner) { 202 case REFINER_NOOP: break; 203 case REFINER_SIMPLEX_2D: 204 for (d = 0; d < 2; ++d) { 205 if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 206 sum += point[d]; 207 } 208 if (sum > 1.0e-10) {*inside = PETSC_FALSE; break;} 209 break; 210 case REFINER_HEX_2D: 211 for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*inside = PETSC_FALSE; break;} 212 break; 213 default: 214 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 215 } 216 PetscFunctionReturn(0); 217 } 218 219 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 220 { 221 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 222 PetscErrorCode ierr; 223 224 PetscFunctionBegin; 225 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 226 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 227 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 228 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 229 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 230 switch (refiner) { 231 case REFINER_NOOP: 232 break; 233 case REFINER_SIMPLEX_1D: 234 depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */ 235 depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */ 236 break; 237 case REFINER_SIMPLEX_2D: 238 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 239 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 240 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 241 break; 242 case REFINER_HYBRID_SIMPLEX_2D: 243 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 244 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 245 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 246 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 */ 247 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, Hybrid cells split into 2 cells */ 248 break; 249 case REFINER_SIMPLEX_TO_HEX_2D: 250 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 251 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 252 depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */ 253 break; 254 case REFINER_HEX_2D: 255 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 256 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 257 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 258 break; 259 case REFINER_HYBRID_HEX_2D: 260 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 261 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 262 /* Quadrilateral */ 263 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 264 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 265 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 266 /* Segment Prisms */ 267 depthSize[0] += 0; /* No hybrid vertices */ 268 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 269 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 270 break; 271 case REFINER_SIMPLEX_3D: 272 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 273 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 */ 274 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 275 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 276 break; 277 case REFINER_HYBRID_SIMPLEX_3D: 278 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 279 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 280 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 281 /* Tetrahedra */ 282 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 283 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 */ 284 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 285 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 286 /* Triangular Prisms */ 287 depthSize[0] += 0; /* No hybrid vertices */ 288 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 289 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 290 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 291 break; 292 case REFINER_SIMPLEX_TO_HEX_3D: 293 depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */ 294 depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + 4*(cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 4 for each cell */ 295 depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */ 296 depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 297 break; 298 case REFINER_HEX_3D: 299 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 300 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 */ 301 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 302 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 303 break; 304 case REFINER_HYBRID_HEX_3D: 305 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 306 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 307 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 308 /* Hexahedra */ 309 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 310 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 */ 311 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 312 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 313 /* Quadrilateral Prisms */ 314 depthSize[0] += 0; /* No hybrid vertices */ 315 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 316 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 317 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 318 break; 319 default: 320 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 321 } 322 PetscFunctionReturn(0); 323 } 324 325 /* Return triangle edge for orientation o, if it is r for o == 0 */ 326 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 327 return (o < 0 ? 2-(o+r) : o+r)%3; 328 } 329 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 330 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 331 } 332 333 /* Return triangle subface for orientation o, if it is r for o == 0 */ 334 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 335 return (o < 0 ? 3-(o+r) : o+r)%3; 336 } 337 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 338 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 339 } 340 341 /* Return the interior edge number connecting the midpoints of the triangle edges r 342 and r+1 in the transitive closure for triangle orientation o */ 343 PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) { 344 return (o < 0 ? 1-(o+r) : o+r)%3; 345 } 346 PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) { 347 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 348 } 349 350 /* Return the interior edge number connecting the midpoint of the triangle edge r 351 (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */ 352 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) { 353 return (o < 0 ? 2-(o+r) : o+r)%3; 354 } 355 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) { 356 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 357 } 358 359 /* Return quad edge for orientation o, if it is r for o == 0 */ 360 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 361 return (o < 0 ? 3-(o+r) : o+r)%4; 362 } 363 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 364 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 365 } 366 367 /* Return quad subface for orientation o, if it is r for o == 0 */ 368 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 369 return (o < 0 ? 4-(o+r) : o+r)%4; 370 } 371 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 372 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 373 } 374 375 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 376 { 377 PetscInt depth, cStart, cStartNew, cEnd, cMax, c, vStart, vStartNew, vEnd, vMax, v, fStart, fStartNew, fEnd, fMax, f, eStart, eStartNew, eEnd, eMax, e, r; 378 PetscErrorCode ierr; 379 380 PetscFunctionBegin; 381 if (!refiner) PetscFunctionReturn(0); 382 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 383 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 384 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 385 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 386 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 387 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 388 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 389 switch (refiner) { 390 case REFINER_SIMPLEX_1D: 391 /* All cells have 2 vertices */ 392 for (c = cStart; c < cEnd; ++c) { 393 for (r = 0; r < 2; ++r) { 394 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 395 396 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 397 } 398 } 399 /* Old vertices have identical supports */ 400 for (v = vStart; v < vEnd; ++v) { 401 const PetscInt newp = vStartNew + (v - vStart); 402 PetscInt size; 403 404 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 405 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 406 } 407 /* Cell vertices have support 2 */ 408 for (c = cStart; c < cEnd; ++c) { 409 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 410 411 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 412 } 413 break; 414 case REFINER_SIMPLEX_2D: 415 /* All cells have 3 faces */ 416 for (c = cStart; c < cEnd; ++c) { 417 for (r = 0; r < 4; ++r) { 418 const PetscInt newp = (c - cStart)*4 + r; 419 420 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 421 } 422 } 423 /* Split faces have 2 vertices and the same cells as the parent */ 424 for (f = fStart; f < fEnd; ++f) { 425 for (r = 0; r < 2; ++r) { 426 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 427 PetscInt size; 428 429 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 430 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 431 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 432 } 433 } 434 /* Interior faces have 2 vertices and 2 cells */ 435 for (c = cStart; c < cEnd; ++c) { 436 for (r = 0; r < 3; ++r) { 437 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 438 439 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 440 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 441 } 442 } 443 /* Old vertices have identical supports */ 444 for (v = vStart; v < vEnd; ++v) { 445 const PetscInt newp = vStartNew + (v - vStart); 446 PetscInt size; 447 448 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 449 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 450 } 451 /* Face vertices have 2 + cells*2 supports */ 452 for (f = fStart; f < fEnd; ++f) { 453 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 454 PetscInt size; 455 456 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 457 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 458 } 459 break; 460 case REFINER_SIMPLEX_TO_HEX_2D: 461 /* All cells have 4 faces */ 462 for (c = cStart; c < cEnd; ++c) { 463 for (r = 0; r < 3; ++r) { 464 const PetscInt newp = (c - cStart)*3 + r; 465 466 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 467 } 468 } 469 /* Split faces have 2 vertices and the same cells as the parent */ 470 for (f = fStart; f < fEnd; ++f) { 471 for (r = 0; r < 2; ++r) { 472 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 473 PetscInt size; 474 475 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 476 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 477 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 478 } 479 } 480 /* Interior faces have 2 vertices and 2 cells */ 481 for (c = cStart; c < cEnd; ++c) { 482 for (r = 0; r < 3; ++r) { 483 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 484 485 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 486 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 487 } 488 } 489 /* Old vertices have identical supports */ 490 for (v = vStart; v < vEnd; ++v) { 491 const PetscInt newp = vStartNew + (v - vStart); 492 PetscInt size; 493 494 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 495 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 496 } 497 /* Split-face vertices have cells + 2 supports */ 498 for (f = fStart; f < fEnd; ++f) { 499 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 500 PetscInt size; 501 502 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 503 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 504 } 505 /* Interior vertices have 3 supports */ 506 for (c = cStart; c < cEnd; ++c) { 507 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 508 509 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 510 } 511 break; 512 case REFINER_HEX_2D: 513 /* All cells have 4 faces */ 514 for (c = cStart; c < cEnd; ++c) { 515 for (r = 0; r < 4; ++r) { 516 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 517 518 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 519 } 520 } 521 /* Split faces have 2 vertices and the same cells as the parent */ 522 for (f = fStart; f < fEnd; ++f) { 523 for (r = 0; r < 2; ++r) { 524 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 525 PetscInt size; 526 527 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 528 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 529 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 530 } 531 } 532 /* Interior faces have 2 vertices and 2 cells */ 533 for (c = cStart; c < cEnd; ++c) { 534 for (r = 0; r < 4; ++r) { 535 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 536 537 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 538 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 539 } 540 } 541 /* Old vertices have identical supports */ 542 for (v = vStart; v < vEnd; ++v) { 543 const PetscInt newp = vStartNew + (v - vStart); 544 PetscInt size; 545 546 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 547 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 548 } 549 /* Face vertices have 2 + cells supports */ 550 for (f = fStart; f < fEnd; ++f) { 551 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 552 PetscInt size; 553 554 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 555 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 556 } 557 /* Cell vertices have 4 supports */ 558 for (c = cStart; c < cEnd; ++c) { 559 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 560 561 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 562 } 563 break; 564 case REFINER_HYBRID_SIMPLEX_2D: 565 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 566 cMax = PetscMin(cEnd, cMax); 567 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 568 fMax = PetscMin(fEnd, fMax); 569 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 570 /* Interior cells have 3 faces */ 571 for (c = cStart; c < cMax; ++c) { 572 for (r = 0; r < 4; ++r) { 573 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 574 575 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 576 } 577 } 578 /* Hybrid cells have 4 faces */ 579 for (c = cMax; c < cEnd; ++c) { 580 for (r = 0; r < 2; ++r) { 581 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 582 583 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 584 } 585 } 586 /* Interior split faces have 2 vertices and the same cells as the parent */ 587 for (f = fStart; f < fMax; ++f) { 588 for (r = 0; r < 2; ++r) { 589 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 590 PetscInt size; 591 592 ierr = DMPlexSetConeSize(rdm, newp, 2);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 2 vertices and 2 cells */ 598 for (c = cStart; c < cMax; ++c) { 599 for (r = 0; r < 3; ++r) { 600 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 601 602 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 603 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 604 } 605 } 606 /* Hybrid faces have 2 vertices and the same cells */ 607 for (f = fMax; f < fEnd; ++f) { 608 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 609 PetscInt size; 610 611 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 612 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 613 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 614 } 615 /* Hybrid cell faces have 2 vertices and 2 cells */ 616 for (c = cMax; c < cEnd; ++c) { 617 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 618 619 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 620 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 621 } 622 /* Old vertices have identical supports */ 623 for (v = vStart; v < vEnd; ++v) { 624 const PetscInt newp = vStartNew + (v - vStart); 625 PetscInt size; 626 627 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 628 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 629 } 630 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 631 for (f = fStart; f < fMax; ++f) { 632 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 633 const PetscInt *support; 634 PetscInt size, newSize = 2, s; 635 636 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 637 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 638 for (s = 0; s < size; ++s) { 639 if (support[s] >= cMax) newSize += 1; 640 else newSize += 2; 641 } 642 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 643 } 644 break; 645 case REFINER_HYBRID_HEX_2D: 646 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 647 cMax = PetscMin(cEnd, cMax); 648 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 649 fMax = PetscMin(fEnd, fMax); 650 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 651 /* Interior cells have 4 faces */ 652 for (c = cStart; c < cMax; ++c) { 653 for (r = 0; r < 4; ++r) { 654 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 655 656 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 657 } 658 } 659 /* Hybrid cells have 4 faces */ 660 for (c = cMax; c < cEnd; ++c) { 661 for (r = 0; r < 2; ++r) { 662 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 663 664 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 665 } 666 } 667 /* Interior split faces have 2 vertices and the same cells as the parent */ 668 for (f = fStart; f < fMax; ++f) { 669 for (r = 0; r < 2; ++r) { 670 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 671 PetscInt size; 672 673 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 674 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 675 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 676 } 677 } 678 /* Interior cell faces have 2 vertices and 2 cells */ 679 for (c = cStart; c < cMax; ++c) { 680 for (r = 0; r < 4; ++r) { 681 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 682 683 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 684 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 685 } 686 } 687 /* Hybrid faces have 2 vertices and the same cells */ 688 for (f = fMax; f < fEnd; ++f) { 689 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 690 PetscInt size; 691 692 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 693 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 694 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 695 } 696 /* Hybrid cell faces have 2 vertices and 2 cells */ 697 for (c = cMax; c < cEnd; ++c) { 698 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 699 700 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 701 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 702 } 703 /* Old vertices have identical supports */ 704 for (v = vStart; v < vEnd; ++v) { 705 const PetscInt newp = vStartNew + (v - vStart); 706 PetscInt size; 707 708 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 709 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 710 } 711 /* Face vertices have 2 + cells supports */ 712 for (f = fStart; f < fMax; ++f) { 713 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 714 PetscInt size; 715 716 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 717 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 718 } 719 /* Cell vertices have 4 supports */ 720 for (c = cStart; c < cMax; ++c) { 721 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 722 723 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 724 } 725 break; 726 case REFINER_SIMPLEX_3D: 727 /* All cells have 4 faces */ 728 for (c = cStart; c < cEnd; ++c) { 729 for (r = 0; r < 8; ++r) { 730 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 731 732 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 733 } 734 } 735 /* Split faces have 3 edges and the same cells as the parent */ 736 for (f = fStart; f < fEnd; ++f) { 737 for (r = 0; r < 4; ++r) { 738 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 739 PetscInt size; 740 741 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 742 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 743 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 744 } 745 } 746 /* Interior cell faces have 3 edges and 2 cells */ 747 for (c = cStart; c < cEnd; ++c) { 748 for (r = 0; r < 8; ++r) { 749 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 750 751 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 752 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 753 } 754 } 755 /* Split edges have 2 vertices and the same faces */ 756 for (e = eStart; e < eEnd; ++e) { 757 for (r = 0; r < 2; ++r) { 758 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 759 PetscInt size; 760 761 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 762 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 763 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 764 } 765 } 766 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 767 for (f = fStart; f < fEnd; ++f) { 768 for (r = 0; r < 3; ++r) { 769 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 770 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 771 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 772 773 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 774 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 775 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 776 for (s = 0; s < supportSize; ++s) { 777 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 778 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 779 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 780 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 781 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 782 er = GetTriMidEdgeInverse_Static(ornt[c], r); 783 if (er == eint[c]) { 784 intFaces += 1; 785 } else { 786 intFaces += 2; 787 } 788 } 789 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 790 } 791 } 792 /* Interior cell edges have 2 vertices and 4 faces */ 793 for (c = cStart; c < cEnd; ++c) { 794 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 795 796 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 797 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 798 } 799 /* Old vertices have identical supports */ 800 for (v = vStart; v < vEnd; ++v) { 801 const PetscInt newp = vStartNew + (v - vStart); 802 PetscInt size; 803 804 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 805 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 806 } 807 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 808 for (e = eStart; e < eEnd; ++e) { 809 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 810 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 811 812 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 813 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 814 for (s = 0; s < starSize*2; s += 2) { 815 const PetscInt *cone, *ornt; 816 PetscInt e01, e23; 817 818 if ((star[s] >= cStart) && (star[s] < cEnd)) { 819 /* Check edge 0-1 */ 820 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 821 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 822 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 823 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 824 /* Check edge 2-3 */ 825 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 826 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 827 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 828 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 829 if ((e01 == e) || (e23 == e)) ++cellSize; 830 } 831 } 832 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 833 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 834 } 835 break; 836 case REFINER_HYBRID_SIMPLEX_3D: 837 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 838 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 839 /* Interior cells have 4 faces */ 840 for (c = cStart; c < cMax; ++c) { 841 for (r = 0; r < 8; ++r) { 842 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 843 844 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 845 } 846 } 847 /* Hybrid cells have 5 faces */ 848 for (c = cMax; c < cEnd; ++c) { 849 for (r = 0; r < 4; ++r) { 850 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 851 852 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 853 } 854 } 855 /* Interior split faces have 3 edges and the same cells as the parent */ 856 for (f = fStart; f < fMax; ++f) { 857 for (r = 0; r < 4; ++r) { 858 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 859 PetscInt size; 860 861 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 862 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 863 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 864 } 865 } 866 /* Interior cell faces have 3 edges and 2 cells */ 867 for (c = cStart; c < cMax; ++c) { 868 for (r = 0; r < 8; ++r) { 869 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 870 871 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 872 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 873 } 874 } 875 /* Hybrid split faces have 4 edges and the same cells as the parent */ 876 for (f = fMax; f < fEnd; ++f) { 877 for (r = 0; r < 2; ++r) { 878 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 879 PetscInt size; 880 881 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 882 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 883 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 884 } 885 } 886 /* Hybrid cells faces have 4 edges and 2 cells */ 887 for (c = cMax; c < cEnd; ++c) { 888 for (r = 0; r < 3; ++r) { 889 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 890 891 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 892 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 893 } 894 } 895 /* Interior split edges have 2 vertices and the same faces */ 896 for (e = eStart; e < eMax; ++e) { 897 for (r = 0; r < 2; ++r) { 898 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 899 PetscInt size; 900 901 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 902 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 903 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 904 } 905 } 906 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 907 for (f = fStart; f < fMax; ++f) { 908 for (r = 0; r < 3; ++r) { 909 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 910 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 911 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 912 913 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 914 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 915 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 916 for (s = 0; s < supportSize; ++s) { 917 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 918 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 919 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 920 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 921 if (support[s] < cMax) { 922 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 923 er = GetTriMidEdgeInverse_Static(ornt[c], r); 924 if (er == eint[c]) { 925 intFaces += 1; 926 } else { 927 intFaces += 2; 928 } 929 } else { 930 intFaces += 1; 931 } 932 } 933 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 934 } 935 } 936 /* Interior cell edges have 2 vertices and 4 faces */ 937 for (c = cStart; c < cMax; ++c) { 938 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 939 940 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 941 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 942 } 943 /* Hybrid edges have 2 vertices and the same faces */ 944 for (e = eMax; e < eEnd; ++e) { 945 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 946 PetscInt size; 947 948 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 949 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 950 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 951 } 952 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 953 for (f = fMax; f < fEnd; ++f) { 954 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 955 PetscInt size; 956 957 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 958 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 959 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 960 } 961 /* Interior vertices have identical supports */ 962 for (v = vStart; v < vEnd; ++v) { 963 const PetscInt newp = vStartNew + (v - vStart); 964 PetscInt size; 965 966 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 967 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 968 } 969 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 970 for (e = eStart; e < eMax; ++e) { 971 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 972 const PetscInt *support; 973 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 974 975 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 976 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 977 for (s = 0; s < size; ++s) { 978 if (support[s] < fMax) faceSize += 2; 979 else faceSize += 1; 980 } 981 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 982 for (s = 0; s < starSize*2; s += 2) { 983 const PetscInt *cone, *ornt; 984 PetscInt e01, e23; 985 986 if ((star[s] >= cStart) && (star[s] < cMax)) { 987 /* Check edge 0-1 */ 988 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 989 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 990 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 991 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 992 /* Check edge 2-3 */ 993 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 994 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 995 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 996 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 997 if ((e01 == e) || (e23 == e)) ++cellSize; 998 } 999 } 1000 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1001 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 1002 } 1003 break; 1004 case REFINER_SIMPLEX_TO_HEX_3D: 1005 /* All cells have 6 faces */ 1006 for (c = cStart; c < cEnd; ++c) { 1007 for (r = 0; r < 4; ++r) { 1008 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1009 1010 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1011 } 1012 } 1013 /* Split faces have 4 edges and the same cells as the parent */ 1014 for (f = fStart; f < fEnd; ++f) { 1015 for (r = 0; r < 3; ++r) { 1016 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1017 PetscInt size; 1018 1019 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1020 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1021 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1022 } 1023 } 1024 /* Interior cell faces have 4 edges and 2 cells */ 1025 for (c = cStart; c < cEnd; ++c) { 1026 for (r = 0; r < 6; ++r) { 1027 const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r; 1028 1029 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1030 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1031 } 1032 } 1033 /* Split edges have 2 vertices and the same faces */ 1034 for (e = eStart; e < eEnd; ++e) { 1035 for (r = 0; r < 2; ++r) { 1036 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1037 PetscInt size; 1038 1039 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1040 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1041 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1042 } 1043 } 1044 /* Face edges have 2 vertices and 2 + cell faces supports */ 1045 for (f = fStart; f < fEnd; ++f) { 1046 for (r = 0; r < 3; ++r) { 1047 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1048 PetscInt size; 1049 1050 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1051 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1052 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1053 } 1054 } 1055 /* Interior cell edges have 2 vertices and 3 faces */ 1056 for (c = cStart; c < cEnd; ++c) { 1057 for (r = 0; r < 4; ++r) { 1058 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 1059 1060 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1061 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1062 } 1063 } 1064 /* Old vertices have identical supports */ 1065 for (v = vStart; v < vEnd; ++v) { 1066 const PetscInt newp = vStartNew + (v - vStart); 1067 PetscInt size; 1068 1069 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1070 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1071 } 1072 /* Edge vertices have 2 + faces supports */ 1073 for (e = eStart; e < eEnd; ++e) { 1074 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1075 PetscInt size; 1076 1077 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1078 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1079 } 1080 /* Face vertices have 3 + cells supports */ 1081 for (f = fStart; f < fEnd; ++f) { 1082 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 1083 PetscInt size; 1084 1085 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1086 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1087 } 1088 /* Interior cell vertices have 4 supports */ 1089 for (c = cStart; c < cEnd; ++c) { 1090 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart; 1091 1092 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1093 } 1094 break; 1095 case REFINER_HEX_3D: 1096 /* All cells have 6 faces */ 1097 for (c = cStart; c < cEnd; ++c) { 1098 for (r = 0; r < 8; ++r) { 1099 const PetscInt newp = (c - cStart)*8 + r; 1100 1101 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1102 } 1103 } 1104 /* Split faces have 4 edges and the same cells as the parent */ 1105 for (f = fStart; f < fEnd; ++f) { 1106 for (r = 0; r < 4; ++r) { 1107 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1108 PetscInt size; 1109 1110 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1111 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1112 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1113 } 1114 } 1115 /* Interior faces have 4 edges and 2 cells */ 1116 for (c = cStart; c < cEnd; ++c) { 1117 for (r = 0; r < 12; ++r) { 1118 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 1119 1120 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1121 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1122 } 1123 } 1124 /* Split edges have 2 vertices and the same faces as the parent */ 1125 for (e = eStart; e < eEnd; ++e) { 1126 for (r = 0; r < 2; ++r) { 1127 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1128 PetscInt size; 1129 1130 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1131 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1132 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1133 } 1134 } 1135 /* Face edges have 2 vertices and 2+cells faces */ 1136 for (f = fStart; f < fEnd; ++f) { 1137 for (r = 0; r < 4; ++r) { 1138 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 1139 PetscInt size; 1140 1141 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1142 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1143 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1144 } 1145 } 1146 /* Cell edges have 2 vertices and 4 faces */ 1147 for (c = cStart; c < cEnd; ++c) { 1148 for (r = 0; r < 6; ++r) { 1149 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 1150 1151 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1152 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1153 } 1154 } 1155 /* Old vertices have identical supports */ 1156 for (v = vStart; v < vEnd; ++v) { 1157 const PetscInt newp = vStartNew + (v - vStart); 1158 PetscInt size; 1159 1160 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1161 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1162 } 1163 /* Edge vertices have 2 + faces supports */ 1164 for (e = eStart; e < eEnd; ++e) { 1165 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1166 PetscInt size; 1167 1168 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1169 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1170 } 1171 /* Face vertices have 4 + cells supports */ 1172 for (f = fStart; f < fEnd; ++f) { 1173 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 1174 PetscInt size; 1175 1176 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1177 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1178 } 1179 /* Cell vertices have 6 supports */ 1180 for (c = cStart; c < cEnd; ++c) { 1181 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 1182 1183 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1184 } 1185 break; 1186 case REFINER_HYBRID_HEX_3D: 1187 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 1188 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1189 /* Interior cells have 6 faces */ 1190 for (c = cStart; c < cMax; ++c) { 1191 for (r = 0; r < 8; ++r) { 1192 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1193 1194 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1195 } 1196 } 1197 /* Hybrid cells have 6 faces */ 1198 for (c = cMax; c < cEnd; ++c) { 1199 for (r = 0; r < 4; ++r) { 1200 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1201 1202 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1203 } 1204 } 1205 /* Interior split faces have 4 edges and the same cells as the parent */ 1206 for (f = fStart; f < fMax; ++f) { 1207 for (r = 0; r < 4; ++r) { 1208 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1209 PetscInt size; 1210 1211 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1212 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1213 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1214 } 1215 } 1216 /* Interior cell faces have 4 edges and 2 cells */ 1217 for (c = cStart; c < cMax; ++c) { 1218 for (r = 0; r < 12; ++r) { 1219 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1220 1221 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1222 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1223 } 1224 } 1225 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1226 for (f = fMax; f < fEnd; ++f) { 1227 for (r = 0; r < 2; ++r) { 1228 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1229 PetscInt size; 1230 1231 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1232 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1233 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1234 } 1235 } 1236 /* Hybrid cells faces have 4 edges and 2 cells */ 1237 for (c = cMax; c < cEnd; ++c) { 1238 for (r = 0; r < 4; ++r) { 1239 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1240 1241 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1242 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1243 } 1244 } 1245 /* Interior split edges have 2 vertices and the same faces as the parent */ 1246 for (e = eStart; e < eMax; ++e) { 1247 for (r = 0; r < 2; ++r) { 1248 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1249 PetscInt size; 1250 1251 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1252 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1253 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1254 } 1255 } 1256 /* Interior face edges have 2 vertices and 2+cells faces */ 1257 for (f = fStart; f < fMax; ++f) { 1258 for (r = 0; r < 4; ++r) { 1259 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1260 PetscInt size; 1261 1262 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1263 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1264 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1265 } 1266 } 1267 /* Interior cell edges have 2 vertices and 4 faces */ 1268 for (c = cStart; c < cMax; ++c) { 1269 for (r = 0; r < 6; ++r) { 1270 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1271 1272 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1273 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1274 } 1275 } 1276 /* Hybrid edges have 2 vertices and the same faces */ 1277 for (e = eMax; e < eEnd; ++e) { 1278 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1279 PetscInt size; 1280 1281 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1282 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1283 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1284 } 1285 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1286 for (f = fMax; f < fEnd; ++f) { 1287 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1288 PetscInt size; 1289 1290 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1291 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1292 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1293 } 1294 /* Hybrid cell edges have 2 vertices and 4 faces */ 1295 for (c = cMax; c < cEnd; ++c) { 1296 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1297 1298 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1299 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1300 } 1301 /* Interior vertices have identical supports */ 1302 for (v = vStart; v < vEnd; ++v) { 1303 const PetscInt newp = vStartNew + (v - vStart); 1304 PetscInt size; 1305 1306 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1307 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1308 } 1309 /* Interior edge vertices have 2 + faces supports */ 1310 for (e = eStart; e < eMax; ++e) { 1311 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1312 PetscInt size; 1313 1314 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1315 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1316 } 1317 /* Interior face vertices have 4 + cells supports */ 1318 for (f = fStart; f < fMax; ++f) { 1319 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1320 PetscInt size; 1321 1322 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1323 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1324 } 1325 /* Interior cell vertices have 6 supports */ 1326 for (c = cStart; c < cMax; ++c) { 1327 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1328 1329 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1330 } 1331 break; 1332 default: 1333 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1334 } 1335 PetscFunctionReturn(0); 1336 } 1337 1338 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1339 { 1340 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1341 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1342 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1343 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 1344 PetscErrorCode ierr; 1345 1346 PetscFunctionBegin; 1347 if (!refiner) PetscFunctionReturn(0); 1348 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1349 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1350 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1351 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1352 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1353 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1354 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1355 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1356 switch (refiner) { 1357 case REFINER_SIMPLEX_1D: 1358 /* Max support size of refined mesh is 2 */ 1359 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1360 /* All cells have 2 vertices */ 1361 for (c = cStart; c < cEnd; ++c) { 1362 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1363 1364 for (r = 0; r < 2; ++r) { 1365 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1366 const PetscInt *cone; 1367 PetscInt coneNew[2]; 1368 1369 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1370 coneNew[0] = vStartNew + (cone[0] - vStart); 1371 coneNew[1] = vStartNew + (cone[1] - vStart); 1372 coneNew[(r+1)%2] = newv; 1373 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1374 #if 1 1375 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew); 1376 for (p = 0; p < 2; ++p) { 1377 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); 1378 } 1379 #endif 1380 } 1381 } 1382 /* Old vertices have identical supports */ 1383 for (v = vStart; v < vEnd; ++v) { 1384 const PetscInt newp = vStartNew + (v - vStart); 1385 const PetscInt *support, *cone; 1386 PetscInt size, s; 1387 1388 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1389 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1390 for (s = 0; s < size; ++s) { 1391 PetscInt r = 0; 1392 1393 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1394 if (cone[1] == v) r = 1; 1395 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1396 } 1397 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1398 #if 1 1399 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1400 for (p = 0; p < size; ++p) { 1401 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); 1402 } 1403 #endif 1404 } 1405 /* Cell vertices have support of 2 cells */ 1406 for (c = cStart; c < cEnd; ++c) { 1407 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1408 1409 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1410 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1411 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1412 #if 1 1413 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1414 for (p = 0; p < 2; ++p) { 1415 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); 1416 } 1417 #endif 1418 } 1419 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1420 break; 1421 case REFINER_SIMPLEX_2D: 1422 /* 1423 2 1424 |\ 1425 | \ 1426 | \ 1427 | \ 1428 | C \ 1429 | \ 1430 | \ 1431 2---1---1 1432 |\ D / \ 1433 | 2 0 \ 1434 |A \ / B \ 1435 0---0-------1 1436 */ 1437 /* All cells have 3 faces */ 1438 for (c = cStart; c < cEnd; ++c) { 1439 const PetscInt newp = cStartNew + (c - cStart)*4; 1440 const PetscInt *cone, *ornt; 1441 PetscInt coneNew[3], orntNew[3]; 1442 1443 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1444 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1445 /* A triangle */ 1446 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1447 orntNew[0] = ornt[0]; 1448 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1449 orntNew[1] = -2; 1450 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1451 orntNew[2] = ornt[2]; 1452 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1453 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1454 #if 1 1455 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); 1456 for (p = 0; p < 3; ++p) { 1457 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); 1458 } 1459 #endif 1460 /* B triangle */ 1461 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1462 orntNew[0] = ornt[0]; 1463 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1464 orntNew[1] = ornt[1]; 1465 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1466 orntNew[2] = -2; 1467 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1468 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1469 #if 1 1470 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); 1471 for (p = 0; p < 3; ++p) { 1472 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); 1473 } 1474 #endif 1475 /* C triangle */ 1476 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1477 orntNew[0] = -2; 1478 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1479 orntNew[1] = ornt[1]; 1480 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1481 orntNew[2] = ornt[2]; 1482 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1483 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1484 #if 1 1485 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); 1486 for (p = 0; p < 3; ++p) { 1487 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); 1488 } 1489 #endif 1490 /* D triangle */ 1491 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1492 orntNew[0] = 0; 1493 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1494 orntNew[1] = 0; 1495 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1496 orntNew[2] = 0; 1497 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1498 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1499 #if 1 1500 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); 1501 for (p = 0; p < 3; ++p) { 1502 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); 1503 } 1504 #endif 1505 } 1506 /* Split faces have 2 vertices and the same cells as the parent */ 1507 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1508 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1509 for (f = fStart; f < fEnd; ++f) { 1510 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1511 1512 for (r = 0; r < 2; ++r) { 1513 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1514 const PetscInt *cone, *ornt, *support; 1515 PetscInt coneNew[2], coneSize, c, supportSize, s; 1516 1517 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1518 coneNew[0] = vStartNew + (cone[0] - vStart); 1519 coneNew[1] = vStartNew + (cone[1] - vStart); 1520 coneNew[(r+1)%2] = newv; 1521 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1522 #if 1 1523 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1524 for (p = 0; p < 2; ++p) { 1525 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); 1526 } 1527 #endif 1528 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1529 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1530 for (s = 0; s < supportSize; ++s) { 1531 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1532 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1533 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1534 for (c = 0; c < coneSize; ++c) { 1535 if (cone[c] == f) break; 1536 } 1537 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1538 } 1539 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1540 #if 1 1541 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1542 for (p = 0; p < supportSize; ++p) { 1543 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); 1544 } 1545 #endif 1546 } 1547 } 1548 /* Interior faces have 2 vertices and 2 cells */ 1549 for (c = cStart; c < cEnd; ++c) { 1550 const PetscInt *cone; 1551 1552 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1553 for (r = 0; r < 3; ++r) { 1554 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1555 PetscInt coneNew[2]; 1556 PetscInt supportNew[2]; 1557 1558 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1559 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1560 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1561 #if 1 1562 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1563 for (p = 0; p < 2; ++p) { 1564 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); 1565 } 1566 #endif 1567 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1568 supportNew[1] = (c - cStart)*4 + 3; 1569 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1570 #if 1 1571 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1572 for (p = 0; p < 2; ++p) { 1573 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); 1574 } 1575 #endif 1576 } 1577 } 1578 /* Old vertices have identical supports */ 1579 for (v = vStart; v < vEnd; ++v) { 1580 const PetscInt newp = vStartNew + (v - vStart); 1581 const PetscInt *support, *cone; 1582 PetscInt size, s; 1583 1584 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1585 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1586 for (s = 0; s < size; ++s) { 1587 PetscInt r = 0; 1588 1589 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1590 if (cone[1] == v) r = 1; 1591 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1592 } 1593 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1594 #if 1 1595 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1596 for (p = 0; p < size; ++p) { 1597 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); 1598 } 1599 #endif 1600 } 1601 /* Face vertices have 2 + cells*2 supports */ 1602 for (f = fStart; f < fEnd; ++f) { 1603 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1604 const PetscInt *cone, *support; 1605 PetscInt size, s; 1606 1607 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1608 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1609 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1610 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1611 for (s = 0; s < size; ++s) { 1612 PetscInt r = 0; 1613 1614 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1615 if (cone[1] == f) r = 1; 1616 else if (cone[2] == f) r = 2; 1617 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1618 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1619 } 1620 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1621 #if 1 1622 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1623 for (p = 0; p < 2+size*2; ++p) { 1624 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); 1625 } 1626 #endif 1627 } 1628 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1629 break; 1630 case REFINER_SIMPLEX_TO_HEX_2D: 1631 /* 1632 2 1633 |\ 1634 | \ 1635 | \ 1636 | \ 1637 | C \ 1638 | \ 1639 2 1 1640 |\ / \ 1641 | 2 1 \ 1642 | \/ \ 1643 | | \ 1644 |A | B \ 1645 | 0 \ 1646 | | \ 1647 0---0----------1 1648 */ 1649 /* All cells have 4 faces */ 1650 for (c = cStart; c < cEnd; ++c) { 1651 const PetscInt newp = cStartNew + (c - cStart)*3; 1652 const PetscInt *cone, *ornt; 1653 PetscInt coneNew[4], orntNew[4]; 1654 1655 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1656 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1657 /* A quad */ 1658 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1659 orntNew[0] = ornt[0]; 1660 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1661 orntNew[1] = 0; 1662 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1663 orntNew[2] = -2; 1664 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1665 orntNew[3] = ornt[2]; 1666 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1667 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1668 #if 1 1669 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); 1670 for (p = 0; p < 4; ++p) { 1671 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); 1672 } 1673 #endif 1674 /* B quad */ 1675 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1676 orntNew[0] = ornt[0]; 1677 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1678 orntNew[1] = ornt[1]; 1679 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1680 orntNew[2] = 0; 1681 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1682 orntNew[3] = -2; 1683 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1684 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1685 #if 1 1686 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); 1687 for (p = 0; p < 4; ++p) { 1688 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); 1689 } 1690 #endif 1691 /* C quad */ 1692 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1693 orntNew[0] = ornt[1]; 1694 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1695 orntNew[1] = ornt[2]; 1696 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1697 orntNew[2] = 0; 1698 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1699 orntNew[3] = -2; 1700 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1701 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1702 #if 1 1703 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); 1704 for (p = 0; p < 4; ++p) { 1705 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); 1706 } 1707 #endif 1708 } 1709 /* Split faces have 2 vertices and the same cells as the parent */ 1710 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1711 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1712 for (f = fStart; f < fEnd; ++f) { 1713 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1714 1715 for (r = 0; r < 2; ++r) { 1716 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1717 const PetscInt *cone, *ornt, *support; 1718 PetscInt coneNew[2], coneSize, c, supportSize, s; 1719 1720 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1721 coneNew[0] = vStartNew + (cone[0] - vStart); 1722 coneNew[1] = vStartNew + (cone[1] - vStart); 1723 coneNew[(r+1)%2] = newv; 1724 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1725 #if 1 1726 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1727 for (p = 0; p < 2; ++p) { 1728 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); 1729 } 1730 #endif 1731 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1732 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1733 for (s = 0; s < supportSize; ++s) { 1734 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1735 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1736 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1737 for (c = 0; c < coneSize; ++c) { 1738 if (cone[c] == f) break; 1739 } 1740 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1741 } 1742 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1743 #if 1 1744 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1745 for (p = 0; p < supportSize; ++p) { 1746 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); 1747 } 1748 #endif 1749 } 1750 } 1751 /* Interior faces have 2 vertices and 2 cells */ 1752 for (c = cStart; c < cEnd; ++c) { 1753 const PetscInt *cone; 1754 1755 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1756 for (r = 0; r < 3; ++r) { 1757 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1758 PetscInt coneNew[2]; 1759 PetscInt supportNew[2]; 1760 1761 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1762 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1763 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1764 #if 1 1765 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1766 for (p = 0; p < 2; ++p) { 1767 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); 1768 } 1769 #endif 1770 supportNew[0] = (c - cStart)*3 + r%3; 1771 supportNew[1] = (c - cStart)*3 + (r+1)%3; 1772 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1773 #if 1 1774 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1775 for (p = 0; p < 2; ++p) { 1776 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); 1777 } 1778 #endif 1779 } 1780 } 1781 /* Old vertices have identical supports */ 1782 for (v = vStart; v < vEnd; ++v) { 1783 const PetscInt newp = vStartNew + (v - vStart); 1784 const PetscInt *support, *cone; 1785 PetscInt size, s; 1786 1787 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1788 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1789 for (s = 0; s < size; ++s) { 1790 PetscInt r = 0; 1791 1792 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1793 if (cone[1] == v) r = 1; 1794 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1795 } 1796 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1797 #if 1 1798 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1799 for (p = 0; p < size; ++p) { 1800 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); 1801 } 1802 #endif 1803 } 1804 /* Split-face vertices have cells + 2 supports */ 1805 for (f = fStart; f < fEnd; ++f) { 1806 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1807 const PetscInt *cone, *support; 1808 PetscInt size, s; 1809 1810 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1811 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1812 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1813 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1814 for (s = 0; s < size; ++s) { 1815 PetscInt r = 0; 1816 1817 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1818 if (cone[1] == f) r = 1; 1819 else if (cone[2] == f) r = 2; 1820 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1821 } 1822 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1823 #if 1 1824 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1825 for (p = 0; p < 2+size; ++p) { 1826 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); 1827 } 1828 #endif 1829 } 1830 /* Interior vertices vertices have 3 supports */ 1831 for (c = cStart; c < cEnd; ++c) { 1832 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 1833 1834 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1835 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1836 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1837 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1838 } 1839 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1840 break; 1841 case REFINER_HEX_2D: 1842 /* 1843 3---------2---------2 1844 | | | 1845 | D 2 C | 1846 | | | 1847 3----3----0----1----1 1848 | | | 1849 | A 0 B | 1850 | | | 1851 0---------0---------1 1852 */ 1853 /* All cells have 4 faces */ 1854 for (c = cStart; c < cEnd; ++c) { 1855 const PetscInt newp = (c - cStart)*4; 1856 const PetscInt *cone, *ornt; 1857 PetscInt coneNew[4], orntNew[4]; 1858 1859 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1860 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1861 /* A quad */ 1862 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1863 orntNew[0] = ornt[0]; 1864 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1865 orntNew[1] = 0; 1866 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1867 orntNew[2] = -2; 1868 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1869 orntNew[3] = ornt[3]; 1870 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1871 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1872 #if 1 1873 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); 1874 for (p = 0; p < 4; ++p) { 1875 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); 1876 } 1877 #endif 1878 /* B quad */ 1879 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1880 orntNew[0] = ornt[0]; 1881 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1882 orntNew[1] = ornt[1]; 1883 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1884 orntNew[2] = -2; 1885 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1886 orntNew[3] = -2; 1887 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1888 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1889 #if 1 1890 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); 1891 for (p = 0; p < 4; ++p) { 1892 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); 1893 } 1894 #endif 1895 /* C quad */ 1896 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1897 orntNew[0] = 0; 1898 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1899 orntNew[1] = ornt[1]; 1900 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1901 orntNew[2] = ornt[2]; 1902 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1903 orntNew[3] = -2; 1904 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1905 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1906 #if 1 1907 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); 1908 for (p = 0; p < 4; ++p) { 1909 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); 1910 } 1911 #endif 1912 /* D quad */ 1913 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1914 orntNew[0] = 0; 1915 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1916 orntNew[1] = 0; 1917 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1918 orntNew[2] = ornt[2]; 1919 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1920 orntNew[3] = ornt[3]; 1921 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1922 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1923 #if 1 1924 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); 1925 for (p = 0; p < 4; ++p) { 1926 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); 1927 } 1928 #endif 1929 } 1930 /* Split faces have 2 vertices and the same cells as the parent */ 1931 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1932 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1933 for (f = fStart; f < fEnd; ++f) { 1934 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1935 1936 for (r = 0; r < 2; ++r) { 1937 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1938 const PetscInt *cone, *ornt, *support; 1939 PetscInt coneNew[2], coneSize, c, supportSize, s; 1940 1941 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1942 coneNew[0] = vStartNew + (cone[0] - vStart); 1943 coneNew[1] = vStartNew + (cone[1] - vStart); 1944 coneNew[(r+1)%2] = newv; 1945 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1946 #if 1 1947 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1948 for (p = 0; p < 2; ++p) { 1949 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); 1950 } 1951 #endif 1952 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1953 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1954 for (s = 0; s < supportSize; ++s) { 1955 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1956 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1957 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1958 for (c = 0; c < coneSize; ++c) { 1959 if (cone[c] == f) break; 1960 } 1961 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1962 } 1963 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1964 #if 1 1965 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1966 for (p = 0; p < supportSize; ++p) { 1967 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); 1968 } 1969 #endif 1970 } 1971 } 1972 /* Interior faces have 2 vertices and 2 cells */ 1973 for (c = cStart; c < cEnd; ++c) { 1974 const PetscInt *cone; 1975 PetscInt coneNew[2], supportNew[2]; 1976 1977 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1978 for (r = 0; r < 4; ++r) { 1979 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 1980 1981 if (r==1 || r==2) { 1982 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1983 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1984 } else { 1985 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1986 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1987 } 1988 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1989 #if 1 1990 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1991 for (p = 0; p < 2; ++p) { 1992 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); 1993 } 1994 #endif 1995 supportNew[0] = (c - cStart)*4 + r; 1996 supportNew[1] = (c - cStart)*4 + (r+1)%4; 1997 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1998 #if 1 1999 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2000 for (p = 0; p < 2; ++p) { 2001 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); 2002 } 2003 #endif 2004 } 2005 } 2006 /* Old vertices have identical supports */ 2007 for (v = vStart; v < vEnd; ++v) { 2008 const PetscInt newp = vStartNew + (v - vStart); 2009 const PetscInt *support, *cone; 2010 PetscInt size, s; 2011 2012 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2013 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2014 for (s = 0; s < size; ++s) { 2015 PetscInt r = 0; 2016 2017 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2018 if (cone[1] == v) r = 1; 2019 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2020 } 2021 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2022 #if 1 2023 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2024 for (p = 0; p < size; ++p) { 2025 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); 2026 } 2027 #endif 2028 } 2029 /* Face vertices have 2 + cells supports */ 2030 for (f = fStart; f < fEnd; ++f) { 2031 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2032 const PetscInt *cone, *support; 2033 PetscInt size, s; 2034 2035 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2036 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2037 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2038 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2039 for (s = 0; s < size; ++s) { 2040 PetscInt r = 0; 2041 2042 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2043 if (cone[1] == f) r = 1; 2044 else if (cone[2] == f) r = 2; 2045 else if (cone[3] == f) r = 3; 2046 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 2047 } 2048 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2049 #if 1 2050 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2051 for (p = 0; p < 2+size; ++p) { 2052 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); 2053 } 2054 #endif 2055 } 2056 /* Cell vertices have 4 supports */ 2057 for (c = cStart; c < cEnd; ++c) { 2058 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2059 PetscInt supportNew[4]; 2060 2061 for (r = 0; r < 4; ++r) { 2062 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2063 } 2064 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2065 } 2066 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2067 break; 2068 case REFINER_HYBRID_SIMPLEX_2D: 2069 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2070 cMax = PetscMin(cEnd, cMax); 2071 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2072 fMax = PetscMin(fEnd, fMax); 2073 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2074 /* Interior cells have 3 faces */ 2075 for (c = cStart; c < cMax; ++c) { 2076 const PetscInt newp = cStartNew + (c - cStart)*4; 2077 const PetscInt *cone, *ornt; 2078 PetscInt coneNew[3], orntNew[3]; 2079 2080 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2081 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2082 /* A triangle */ 2083 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2084 orntNew[0] = ornt[0]; 2085 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2086 orntNew[1] = -2; 2087 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2088 orntNew[2] = ornt[2]; 2089 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2090 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2091 #if 1 2092 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); 2093 for (p = 0; p < 3; ++p) { 2094 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); 2095 } 2096 #endif 2097 /* B triangle */ 2098 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2099 orntNew[0] = ornt[0]; 2100 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2101 orntNew[1] = ornt[1]; 2102 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2103 orntNew[2] = -2; 2104 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2105 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2106 #if 1 2107 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); 2108 for (p = 0; p < 3; ++p) { 2109 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); 2110 } 2111 #endif 2112 /* C triangle */ 2113 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2114 orntNew[0] = -2; 2115 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2116 orntNew[1] = ornt[1]; 2117 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2118 orntNew[2] = ornt[2]; 2119 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2120 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2121 #if 1 2122 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); 2123 for (p = 0; p < 3; ++p) { 2124 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); 2125 } 2126 #endif 2127 /* D triangle */ 2128 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2129 orntNew[0] = 0; 2130 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2131 orntNew[1] = 0; 2132 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2133 orntNew[2] = 0; 2134 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2135 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2136 #if 1 2137 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); 2138 for (p = 0; p < 3; ++p) { 2139 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); 2140 } 2141 #endif 2142 } 2143 /* 2144 2----3----3 2145 | | 2146 | B | 2147 | | 2148 0----4--- 1 2149 | | 2150 | A | 2151 | | 2152 0----2----1 2153 */ 2154 /* Hybrid cells have 4 faces */ 2155 for (c = cMax; c < cEnd; ++c) { 2156 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2157 const PetscInt *cone, *ornt; 2158 PetscInt coneNew[4], orntNew[4], r; 2159 2160 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2161 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2162 r = (ornt[0] < 0 ? 1 : 0); 2163 /* A quad */ 2164 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2165 orntNew[0] = ornt[0]; 2166 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2167 orntNew[1] = ornt[1]; 2168 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2169 orntNew[2+r] = 0; 2170 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2171 orntNew[3-r] = 0; 2172 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2173 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2174 #if 1 2175 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); 2176 for (p = 0; p < 4; ++p) { 2177 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); 2178 } 2179 #endif 2180 /* B quad */ 2181 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2182 orntNew[0] = ornt[0]; 2183 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2184 orntNew[1] = ornt[1]; 2185 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2186 orntNew[2+r] = 0; 2187 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2188 orntNew[3-r] = 0; 2189 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2190 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2191 #if 1 2192 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); 2193 for (p = 0; p < 4; ++p) { 2194 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); 2195 } 2196 #endif 2197 } 2198 /* Interior split faces have 2 vertices and the same cells as the parent */ 2199 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2200 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2201 for (f = fStart; f < fMax; ++f) { 2202 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2203 2204 for (r = 0; r < 2; ++r) { 2205 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2206 const PetscInt *cone, *ornt, *support; 2207 PetscInt coneNew[2], coneSize, c, supportSize, s; 2208 2209 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2210 coneNew[0] = vStartNew + (cone[0] - vStart); 2211 coneNew[1] = vStartNew + (cone[1] - vStart); 2212 coneNew[(r+1)%2] = newv; 2213 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2214 #if 1 2215 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2216 for (p = 0; p < 2; ++p) { 2217 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); 2218 } 2219 #endif 2220 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2221 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2222 for (s = 0; s < supportSize; ++s) { 2223 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2224 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2225 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2226 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2227 if (support[s] >= cMax) { 2228 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2229 } else { 2230 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2231 } 2232 } 2233 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2234 #if 1 2235 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2236 for (p = 0; p < supportSize; ++p) { 2237 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); 2238 } 2239 #endif 2240 } 2241 } 2242 /* Interior cell faces have 2 vertices and 2 cells */ 2243 for (c = cStart; c < cMax; ++c) { 2244 const PetscInt *cone; 2245 2246 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2247 for (r = 0; r < 3; ++r) { 2248 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 2249 PetscInt coneNew[2]; 2250 PetscInt supportNew[2]; 2251 2252 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2253 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 2254 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2255 #if 1 2256 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2257 for (p = 0; p < 2; ++p) { 2258 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); 2259 } 2260 #endif 2261 supportNew[0] = (c - cStart)*4 + (r+1)%3; 2262 supportNew[1] = (c - cStart)*4 + 3; 2263 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2264 #if 1 2265 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2266 for (p = 0; p < 2; ++p) { 2267 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); 2268 } 2269 #endif 2270 } 2271 } 2272 /* Interior hybrid faces have 2 vertices and the same cells */ 2273 for (f = fMax; f < fEnd; ++f) { 2274 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 2275 const PetscInt *cone, *ornt; 2276 const PetscInt *support; 2277 PetscInt coneNew[2]; 2278 PetscInt supportNew[2]; 2279 PetscInt size, s, r; 2280 2281 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2282 coneNew[0] = vStartNew + (cone[0] - vStart); 2283 coneNew[1] = vStartNew + (cone[1] - vStart); 2284 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2285 #if 1 2286 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2287 for (p = 0; p < 2; ++p) { 2288 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); 2289 } 2290 #endif 2291 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2292 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2293 for (s = 0; s < size; ++s) { 2294 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2295 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2296 for (r = 0; r < 2; ++r) { 2297 if (cone[r+2] == f) break; 2298 } 2299 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 2300 } 2301 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2302 #if 1 2303 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2304 for (p = 0; p < size; ++p) { 2305 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); 2306 } 2307 #endif 2308 } 2309 /* Cell hybrid faces have 2 vertices and 2 cells */ 2310 for (c = cMax; c < cEnd; ++c) { 2311 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2312 const PetscInt *cone; 2313 PetscInt coneNew[2]; 2314 PetscInt supportNew[2]; 2315 2316 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2317 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2318 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2319 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2320 #if 1 2321 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2322 for (p = 0; p < 2; ++p) { 2323 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); 2324 } 2325 #endif 2326 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2327 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2328 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2329 #if 1 2330 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2331 for (p = 0; p < 2; ++p) { 2332 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); 2333 } 2334 #endif 2335 } 2336 /* Old vertices have identical supports */ 2337 for (v = vStart; v < vEnd; ++v) { 2338 const PetscInt newp = vStartNew + (v - vStart); 2339 const PetscInt *support, *cone; 2340 PetscInt size, s; 2341 2342 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2343 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2344 for (s = 0; s < size; ++s) { 2345 if (support[s] >= fMax) { 2346 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 2347 } else { 2348 PetscInt r = 0; 2349 2350 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2351 if (cone[1] == v) r = 1; 2352 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2353 } 2354 } 2355 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2356 #if 1 2357 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2358 for (p = 0; p < size; ++p) { 2359 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); 2360 } 2361 #endif 2362 } 2363 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 2364 for (f = fStart; f < fMax; ++f) { 2365 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2366 const PetscInt *cone, *support; 2367 PetscInt size, newSize = 2, s; 2368 2369 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2370 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2371 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2372 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2373 for (s = 0; s < size; ++s) { 2374 PetscInt r = 0; 2375 2376 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2377 if (support[s] >= cMax) { 2378 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 2379 2380 newSize += 1; 2381 } else { 2382 if (cone[1] == f) r = 1; 2383 else if (cone[2] == f) r = 2; 2384 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 2385 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 2386 2387 newSize += 2; 2388 } 2389 } 2390 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2391 #if 1 2392 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2393 for (p = 0; p < newSize; ++p) { 2394 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); 2395 } 2396 #endif 2397 } 2398 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2399 break; 2400 case REFINER_HYBRID_HEX_2D: 2401 /* Hybrid Hex 2D */ 2402 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2403 cMax = PetscMin(cEnd, cMax); 2404 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2405 fMax = PetscMin(fEnd, fMax); 2406 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2407 /* Interior cells have 4 faces */ 2408 for (c = cStart; c < cMax; ++c) { 2409 const PetscInt newp = cStartNew + (c - cStart)*4; 2410 const PetscInt *cone, *ornt; 2411 PetscInt coneNew[4], orntNew[4]; 2412 2413 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2414 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2415 /* A quad */ 2416 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2417 orntNew[0] = ornt[0]; 2418 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 2419 orntNew[1] = 0; 2420 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2421 orntNew[2] = -2; 2422 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2423 orntNew[3] = ornt[3]; 2424 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2425 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2426 #if 1 2427 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); 2428 for (p = 0; p < 4; ++p) { 2429 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); 2430 } 2431 #endif 2432 /* B quad */ 2433 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2434 orntNew[0] = ornt[0]; 2435 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2436 orntNew[1] = ornt[1]; 2437 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2438 orntNew[2] = 0; 2439 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 2440 orntNew[3] = -2; 2441 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2442 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2443 #if 1 2444 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); 2445 for (p = 0; p < 4; ++p) { 2446 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); 2447 } 2448 #endif 2449 /* C quad */ 2450 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2451 orntNew[0] = -2; 2452 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2453 orntNew[1] = ornt[1]; 2454 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2455 orntNew[2] = ornt[2]; 2456 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2457 orntNew[3] = 0; 2458 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2459 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2460 #if 1 2461 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); 2462 for (p = 0; p < 4; ++p) { 2463 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); 2464 } 2465 #endif 2466 /* D quad */ 2467 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2468 orntNew[0] = 0; 2469 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2470 orntNew[1] = -2; 2471 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2472 orntNew[2] = ornt[2]; 2473 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2474 orntNew[3] = ornt[3]; 2475 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2476 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2477 #if 1 2478 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); 2479 for (p = 0; p < 4; ++p) { 2480 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); 2481 } 2482 #endif 2483 } 2484 /* 2485 2----3----3 2486 | | 2487 | B | 2488 | | 2489 0----4--- 1 2490 | | 2491 | A | 2492 | | 2493 0----2----1 2494 */ 2495 /* Hybrid cells have 4 faces */ 2496 for (c = cMax; c < cEnd; ++c) { 2497 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2498 const PetscInt *cone, *ornt; 2499 PetscInt coneNew[4], orntNew[4]; 2500 2501 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2502 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2503 /* A quad */ 2504 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2505 orntNew[0] = ornt[0]; 2506 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2507 orntNew[1] = ornt[1]; 2508 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 2509 orntNew[2] = 0; 2510 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2511 orntNew[3] = 0; 2512 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2513 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2514 #if 1 2515 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); 2516 for (p = 0; p < 4; ++p) { 2517 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); 2518 } 2519 #endif 2520 /* B quad */ 2521 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2522 orntNew[0] = ornt[0]; 2523 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2524 orntNew[1] = ornt[1]; 2525 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2526 orntNew[2] = 0; 2527 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 2528 orntNew[3] = 0; 2529 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2530 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2531 #if 1 2532 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); 2533 for (p = 0; p < 4; ++p) { 2534 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); 2535 } 2536 #endif 2537 } 2538 /* Interior split faces have 2 vertices and the same cells as the parent */ 2539 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2540 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2541 for (f = fStart; f < fMax; ++f) { 2542 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2543 2544 for (r = 0; r < 2; ++r) { 2545 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2546 const PetscInt *cone, *ornt, *support; 2547 PetscInt coneNew[2], coneSize, c, supportSize, s; 2548 2549 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2550 coneNew[0] = vStartNew + (cone[0] - vStart); 2551 coneNew[1] = vStartNew + (cone[1] - vStart); 2552 coneNew[(r+1)%2] = newv; 2553 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2554 #if 1 2555 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2556 for (p = 0; p < 2; ++p) { 2557 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); 2558 } 2559 #endif 2560 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2561 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2562 for (s = 0; s < supportSize; ++s) { 2563 if (support[s] >= cMax) { 2564 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2565 } else { 2566 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2567 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2568 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2569 for (c = 0; c < coneSize; ++c) { 2570 if (cone[c] == f) break; 2571 } 2572 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2573 } 2574 } 2575 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2576 #if 1 2577 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2578 for (p = 0; p < supportSize; ++p) { 2579 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); 2580 } 2581 #endif 2582 } 2583 } 2584 /* Interior cell faces have 2 vertices and 2 cells */ 2585 for (c = cStart; c < cMax; ++c) { 2586 const PetscInt *cone; 2587 2588 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2589 for (r = 0; r < 4; ++r) { 2590 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2591 PetscInt coneNew[2], supportNew[2]; 2592 2593 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2594 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2595 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2596 #if 1 2597 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2598 for (p = 0; p < 2; ++p) { 2599 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); 2600 } 2601 #endif 2602 supportNew[0] = (c - cStart)*4 + r; 2603 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2604 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2605 #if 1 2606 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2607 for (p = 0; p < 2; ++p) { 2608 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); 2609 } 2610 #endif 2611 } 2612 } 2613 /* Hybrid faces have 2 vertices and the same cells */ 2614 for (f = fMax; f < fEnd; ++f) { 2615 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 2616 const PetscInt *cone, *support; 2617 PetscInt coneNew[2], supportNew[2]; 2618 PetscInt size, s, r; 2619 2620 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2621 coneNew[0] = vStartNew + (cone[0] - vStart); 2622 coneNew[1] = vStartNew + (cone[1] - vStart); 2623 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2624 #if 1 2625 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2626 for (p = 0; p < 2; ++p) { 2627 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); 2628 } 2629 #endif 2630 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2631 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2632 for (s = 0; s < size; ++s) { 2633 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2634 for (r = 0; r < 2; ++r) { 2635 if (cone[r+2] == f) break; 2636 } 2637 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2638 } 2639 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2640 #if 1 2641 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2642 for (p = 0; p < size; ++p) { 2643 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); 2644 } 2645 #endif 2646 } 2647 /* Cell hybrid faces have 2 vertices and 2 cells */ 2648 for (c = cMax; c < cEnd; ++c) { 2649 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2650 const PetscInt *cone; 2651 PetscInt coneNew[2], supportNew[2]; 2652 2653 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2654 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2655 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2656 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2657 #if 1 2658 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2659 for (p = 0; p < 2; ++p) { 2660 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); 2661 } 2662 #endif 2663 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2664 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2665 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2666 #if 1 2667 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2668 for (p = 0; p < 2; ++p) { 2669 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); 2670 } 2671 #endif 2672 } 2673 /* Old vertices have identical supports */ 2674 for (v = vStart; v < vEnd; ++v) { 2675 const PetscInt newp = vStartNew + (v - vStart); 2676 const PetscInt *support, *cone; 2677 PetscInt size, s; 2678 2679 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2680 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2681 for (s = 0; s < size; ++s) { 2682 if (support[s] >= fMax) { 2683 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2684 } else { 2685 PetscInt r = 0; 2686 2687 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2688 if (cone[1] == v) r = 1; 2689 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2690 } 2691 } 2692 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2693 #if 1 2694 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2695 for (p = 0; p < size; ++p) { 2696 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); 2697 } 2698 #endif 2699 } 2700 /* Face vertices have 2 + cells supports */ 2701 for (f = fStart; f < fMax; ++f) { 2702 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2703 const PetscInt *cone, *support; 2704 PetscInt size, s; 2705 2706 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2707 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2708 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2709 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2710 for (s = 0; s < size; ++s) { 2711 PetscInt r = 0; 2712 2713 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2714 if (support[s] >= cMax) { 2715 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2716 } else { 2717 if (cone[1] == f) r = 1; 2718 else if (cone[2] == f) r = 2; 2719 else if (cone[3] == f) r = 3; 2720 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2721 } 2722 } 2723 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2724 #if 1 2725 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2726 for (p = 0; p < 2+size; ++p) { 2727 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); 2728 } 2729 #endif 2730 } 2731 /* Cell vertices have 4 supports */ 2732 for (c = cStart; c < cMax; ++c) { 2733 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2734 PetscInt supportNew[4]; 2735 2736 for (r = 0; r < 4; ++r) { 2737 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2738 } 2739 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2740 } 2741 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2742 break; 2743 case REFINER_SIMPLEX_3D: 2744 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2745 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2746 for (c = cStart; c < cEnd; ++c) { 2747 const PetscInt newp = cStartNew + (c - cStart)*8; 2748 const PetscInt *cone, *ornt; 2749 PetscInt coneNew[4], orntNew[4]; 2750 2751 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2752 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2753 /* A tetrahedron: {0, a, c, d} */ 2754 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2755 orntNew[0] = ornt[0]; 2756 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2757 orntNew[1] = ornt[1]; 2758 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2759 orntNew[2] = ornt[2]; 2760 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2761 orntNew[3] = 0; 2762 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2763 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2764 #if 1 2765 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); 2766 for (p = 0; p < 4; ++p) { 2767 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2768 } 2769 #endif 2770 /* B tetrahedron: {a, 1, b, e} */ 2771 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2772 orntNew[0] = ornt[0]; 2773 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2774 orntNew[1] = ornt[1]; 2775 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2776 orntNew[2] = 0; 2777 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2778 orntNew[3] = ornt[3]; 2779 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2780 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2781 #if 1 2782 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); 2783 for (p = 0; p < 4; ++p) { 2784 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2785 } 2786 #endif 2787 /* C tetrahedron: {c, b, 2, f} */ 2788 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2789 orntNew[0] = ornt[0]; 2790 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2791 orntNew[1] = 0; 2792 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2793 orntNew[2] = ornt[2]; 2794 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2795 orntNew[3] = ornt[3]; 2796 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2797 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2798 #if 1 2799 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); 2800 for (p = 0; p < 4; ++p) { 2801 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2802 } 2803 #endif 2804 /* D tetrahedron: {d, e, f, 3} */ 2805 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2806 orntNew[0] = 0; 2807 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2808 orntNew[1] = ornt[1]; 2809 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2810 orntNew[2] = ornt[2]; 2811 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2812 orntNew[3] = ornt[3]; 2813 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2814 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2815 #if 1 2816 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); 2817 for (p = 0; p < 4; ++p) { 2818 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2819 } 2820 #endif 2821 /* A' tetrahedron: {c, d, a, f} */ 2822 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2823 orntNew[0] = -3; 2824 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2825 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 2826 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2827 orntNew[2] = 0; 2828 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2829 orntNew[3] = 2; 2830 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2831 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2832 #if 1 2833 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); 2834 for (p = 0; p < 4; ++p) { 2835 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); 2836 } 2837 #endif 2838 /* B' tetrahedron: {e, b, a, f} */ 2839 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2840 orntNew[0] = -2; 2841 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 2842 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 2843 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2844 orntNew[2] = 0; 2845 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2846 orntNew[3] = 0; 2847 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2848 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2849 #if 1 2850 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); 2851 for (p = 0; p < 4; ++p) { 2852 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); 2853 } 2854 #endif 2855 /* C' tetrahedron: {f, a, c, b} */ 2856 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2857 orntNew[0] = -2; 2858 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2859 orntNew[1] = -2; 2860 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2861 orntNew[2] = -1; 2862 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 2863 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 2864 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2865 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2866 #if 1 2867 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); 2868 for (p = 0; p < 4; ++p) { 2869 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); 2870 } 2871 #endif 2872 /* D' tetrahedron: {f, a, e, d} */ 2873 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2874 orntNew[0] = -2; 2875 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2876 orntNew[1] = -1; 2877 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2878 orntNew[2] = -2; 2879 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 2880 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 2881 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2882 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2883 #if 1 2884 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); 2885 for (p = 0; p < 4; ++p) { 2886 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); 2887 } 2888 #endif 2889 } 2890 /* Split faces have 3 edges and the same cells as the parent */ 2891 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2892 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2893 for (f = fStart; f < fEnd; ++f) { 2894 const PetscInt newp = fStartNew + (f - fStart)*4; 2895 const PetscInt *cone, *ornt, *support; 2896 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2897 2898 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2899 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2900 /* A triangle */ 2901 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2902 orntNew[0] = ornt[0]; 2903 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2904 orntNew[1] = -2; 2905 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2906 orntNew[2] = ornt[2]; 2907 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2908 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2909 #if 1 2910 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); 2911 for (p = 0; p < 3; ++p) { 2912 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); 2913 } 2914 #endif 2915 /* B triangle */ 2916 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2917 orntNew[0] = ornt[0]; 2918 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2919 orntNew[1] = ornt[1]; 2920 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2921 orntNew[2] = -2; 2922 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2923 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2924 #if 1 2925 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); 2926 for (p = 0; p < 3; ++p) { 2927 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); 2928 } 2929 #endif 2930 /* C triangle */ 2931 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2932 orntNew[0] = -2; 2933 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2934 orntNew[1] = ornt[1]; 2935 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2936 orntNew[2] = ornt[2]; 2937 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2938 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2939 #if 1 2940 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); 2941 for (p = 0; p < 3; ++p) { 2942 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); 2943 } 2944 #endif 2945 /* D triangle */ 2946 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2947 orntNew[0] = 0; 2948 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2949 orntNew[1] = 0; 2950 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2951 orntNew[2] = 0; 2952 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2953 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2954 #if 1 2955 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); 2956 for (p = 0; p < 3; ++p) { 2957 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); 2958 } 2959 #endif 2960 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2961 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2962 for (r = 0; r < 4; ++r) { 2963 for (s = 0; s < supportSize; ++s) { 2964 PetscInt subf; 2965 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2966 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2967 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2968 for (c = 0; c < coneSize; ++c) { 2969 if (cone[c] == f) break; 2970 } 2971 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2972 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2973 } 2974 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2975 #if 1 2976 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); 2977 for (p = 0; p < supportSize; ++p) { 2978 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); 2979 } 2980 #endif 2981 } 2982 } 2983 /* Interior faces have 3 edges and 2 cells */ 2984 for (c = cStart; c < cEnd; ++c) { 2985 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 2986 const PetscInt *cone, *ornt; 2987 PetscInt coneNew[3], orntNew[3]; 2988 PetscInt supportNew[2]; 2989 2990 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2991 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2992 /* Face A: {c, a, d} */ 2993 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 2994 orntNew[0] = ornt[0] < 0 ? -2 : 0; 2995 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 2996 orntNew[1] = ornt[1] < 0 ? -2 : 0; 2997 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 2998 orntNew[2] = ornt[2] < 0 ? -2 : 0; 2999 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3000 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3001 #if 1 3002 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3003 for (p = 0; p < 3; ++p) { 3004 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); 3005 } 3006 #endif 3007 supportNew[0] = (c - cStart)*8 + 0; 3008 supportNew[1] = (c - cStart)*8 + 0+4; 3009 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3010 #if 1 3011 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3012 for (p = 0; p < 2; ++p) { 3013 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); 3014 } 3015 #endif 3016 ++newp; 3017 /* Face B: {a, b, e} */ 3018 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3019 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3020 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3021 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3022 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3023 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3024 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3025 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3026 #if 1 3027 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3028 for (p = 0; p < 3; ++p) { 3029 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); 3030 } 3031 #endif 3032 supportNew[0] = (c - cStart)*8 + 1; 3033 supportNew[1] = (c - cStart)*8 + 1+4; 3034 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3035 #if 1 3036 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3037 for (p = 0; p < 2; ++p) { 3038 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); 3039 } 3040 #endif 3041 ++newp; 3042 /* Face C: {c, f, b} */ 3043 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3044 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3045 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3046 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3047 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3048 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3049 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3050 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3051 #if 1 3052 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3053 for (p = 0; p < 3; ++p) { 3054 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); 3055 } 3056 #endif 3057 supportNew[0] = (c - cStart)*8 + 2; 3058 supportNew[1] = (c - cStart)*8 + 2+4; 3059 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3060 #if 1 3061 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3062 for (p = 0; p < 2; ++p) { 3063 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); 3064 } 3065 #endif 3066 ++newp; 3067 /* Face D: {d, e, f} */ 3068 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3069 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3070 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3071 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3072 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3073 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3074 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3075 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3076 #if 1 3077 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3078 for (p = 0; p < 3; ++p) { 3079 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); 3080 } 3081 #endif 3082 supportNew[0] = (c - cStart)*8 + 3; 3083 supportNew[1] = (c - cStart)*8 + 3+4; 3084 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3085 #if 1 3086 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3087 for (p = 0; p < 2; ++p) { 3088 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); 3089 } 3090 #endif 3091 ++newp; 3092 /* Face E: {d, f, a} */ 3093 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3094 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3095 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3096 orntNew[1] = -2; 3097 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3098 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3099 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3100 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3101 #if 1 3102 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3103 for (p = 0; p < 3; ++p) { 3104 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); 3105 } 3106 #endif 3107 supportNew[0] = (c - cStart)*8 + 0+4; 3108 supportNew[1] = (c - cStart)*8 + 3+4; 3109 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3110 #if 1 3111 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3112 for (p = 0; p < 2; ++p) { 3113 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); 3114 } 3115 #endif 3116 ++newp; 3117 /* Face F: {c, a, f} */ 3118 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3119 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3120 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3121 orntNew[1] = 0; 3122 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3123 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3124 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3125 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3126 #if 1 3127 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3128 for (p = 0; p < 3; ++p) { 3129 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); 3130 } 3131 #endif 3132 supportNew[0] = (c - cStart)*8 + 0+4; 3133 supportNew[1] = (c - cStart)*8 + 2+4; 3134 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3135 #if 1 3136 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3137 for (p = 0; p < 2; ++p) { 3138 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); 3139 } 3140 #endif 3141 ++newp; 3142 /* Face G: {e, a, f} */ 3143 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3144 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3145 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3146 orntNew[1] = 0; 3147 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3148 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3149 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3150 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3151 #if 1 3152 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3153 for (p = 0; p < 3; ++p) { 3154 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); 3155 } 3156 #endif 3157 supportNew[0] = (c - cStart)*8 + 1+4; 3158 supportNew[1] = (c - cStart)*8 + 3+4; 3159 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3160 #if 1 3161 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3162 for (p = 0; p < 2; ++p) { 3163 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); 3164 } 3165 #endif 3166 ++newp; 3167 /* Face H: {a, b, f} */ 3168 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3169 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3170 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3171 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3172 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3173 orntNew[2] = -2; 3174 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3175 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3176 #if 1 3177 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3178 for (p = 0; p < 3; ++p) { 3179 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); 3180 } 3181 #endif 3182 supportNew[0] = (c - cStart)*8 + 1+4; 3183 supportNew[1] = (c - cStart)*8 + 2+4; 3184 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3185 #if 1 3186 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3187 for (p = 0; p < 2; ++p) { 3188 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); 3189 } 3190 #endif 3191 ++newp; 3192 } 3193 /* Split Edges have 2 vertices and the same faces as the parent */ 3194 for (e = eStart; e < eEnd; ++e) { 3195 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3196 3197 for (r = 0; r < 2; ++r) { 3198 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3199 const PetscInt *cone, *ornt, *support; 3200 PetscInt coneNew[2], coneSize, c, supportSize, s; 3201 3202 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3203 coneNew[0] = vStartNew + (cone[0] - vStart); 3204 coneNew[1] = vStartNew + (cone[1] - vStart); 3205 coneNew[(r+1)%2] = newv; 3206 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3207 #if 1 3208 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3209 for (p = 0; p < 2; ++p) { 3210 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); 3211 } 3212 #endif 3213 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3214 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3215 for (s = 0; s < supportSize; ++s) { 3216 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3217 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3218 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3219 for (c = 0; c < coneSize; ++c) { 3220 if (cone[c] == e) break; 3221 } 3222 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3223 } 3224 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3225 #if 1 3226 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3227 for (p = 0; p < supportSize; ++p) { 3228 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); 3229 } 3230 #endif 3231 } 3232 } 3233 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3234 for (f = fStart; f < fEnd; ++f) { 3235 const PetscInt *cone, *ornt, *support; 3236 PetscInt coneSize, supportSize, s; 3237 3238 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3239 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3240 for (r = 0; r < 3; ++r) { 3241 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3242 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3243 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3244 -1, -1, 1, 6, 0, 4, 3245 2, 5, 3, 4, -1, -1, 3246 -1, -1, 3, 6, 2, 7}; 3247 3248 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3249 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3250 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3251 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3252 #if 1 3253 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3254 for (p = 0; p < 2; ++p) { 3255 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); 3256 } 3257 #endif 3258 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3259 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3260 for (s = 0; s < supportSize; ++s) { 3261 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3262 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3263 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3264 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3265 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3266 er = GetTriMidEdgeInverse_Static(ornt[c], r); 3267 if (er == eint[c]) { 3268 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3269 } else { 3270 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3271 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3272 } 3273 } 3274 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3275 #if 1 3276 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3277 for (p = 0; p < intFaces; ++p) { 3278 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); 3279 } 3280 #endif 3281 } 3282 } 3283 /* Interior edges have 2 vertices and 4 faces */ 3284 for (c = cStart; c < cEnd; ++c) { 3285 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3286 const PetscInt *cone, *ornt, *fcone; 3287 PetscInt coneNew[2], supportNew[4], find; 3288 3289 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3290 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3291 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3292 find = GetTriEdge_Static(ornt[0], 0); 3293 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3294 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3295 find = GetTriEdge_Static(ornt[2], 1); 3296 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3297 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3298 #if 1 3299 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3300 for (p = 0; p < 2; ++p) { 3301 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); 3302 } 3303 #endif 3304 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3305 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3306 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3307 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3308 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3309 #if 1 3310 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3311 for (p = 0; p < 4; ++p) { 3312 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); 3313 } 3314 #endif 3315 } 3316 /* Old vertices have identical supports */ 3317 for (v = vStart; v < vEnd; ++v) { 3318 const PetscInt newp = vStartNew + (v - vStart); 3319 const PetscInt *support, *cone; 3320 PetscInt size, s; 3321 3322 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3323 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3324 for (s = 0; s < size; ++s) { 3325 PetscInt r = 0; 3326 3327 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3328 if (cone[1] == v) r = 1; 3329 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3330 } 3331 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3332 #if 1 3333 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3334 for (p = 0; p < size; ++p) { 3335 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); 3336 } 3337 #endif 3338 } 3339 /* Edge vertices have 2 + face*2 + 0/1 supports */ 3340 for (e = eStart; e < eEnd; ++e) { 3341 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3342 const PetscInt *cone, *support; 3343 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 3344 3345 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3346 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3347 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3348 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3349 for (s = 0; s < size; ++s) { 3350 PetscInt r = 0; 3351 3352 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3353 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3354 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3355 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3356 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3357 } 3358 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3359 for (s = 0; s < starSize*2; s += 2) { 3360 const PetscInt *cone, *ornt; 3361 PetscInt e01, e23; 3362 3363 if ((star[s] >= cStart) && (star[s] < cEnd)) { 3364 /* Check edge 0-1 */ 3365 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3366 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3367 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3368 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3369 /* Check edge 2-3 */ 3370 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3371 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3372 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3373 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3374 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 3375 } 3376 } 3377 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3378 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3379 #if 1 3380 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3381 for (p = 0; p < 2+size*2+cellSize; ++p) { 3382 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); 3383 } 3384 #endif 3385 } 3386 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3387 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3388 break; 3389 case REFINER_HYBRID_SIMPLEX_3D: 3390 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 3391 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3392 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3393 for (c = cStart; c < cMax; ++c) { 3394 const PetscInt newp = cStartNew + (c - cStart)*8; 3395 const PetscInt *cone, *ornt; 3396 PetscInt coneNew[4], orntNew[4]; 3397 3398 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3399 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3400 /* A tetrahedron: {0, a, c, d} */ 3401 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3402 orntNew[0] = ornt[0]; 3403 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3404 orntNew[1] = ornt[1]; 3405 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3406 orntNew[2] = ornt[2]; 3407 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3408 orntNew[3] = 0; 3409 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3410 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3411 #if 1 3412 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); 3413 for (p = 0; p < 4; ++p) { 3414 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 3415 } 3416 #endif 3417 /* B tetrahedron: {a, 1, b, e} */ 3418 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3419 orntNew[0] = ornt[0]; 3420 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3421 orntNew[1] = ornt[1]; 3422 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3423 orntNew[2] = 0; 3424 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3425 orntNew[3] = ornt[3]; 3426 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3427 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3428 #if 1 3429 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); 3430 for (p = 0; p < 4; ++p) { 3431 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 3432 } 3433 #endif 3434 /* C tetrahedron: {c, b, 2, f} */ 3435 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3436 orntNew[0] = ornt[0]; 3437 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3438 orntNew[1] = 0; 3439 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3440 orntNew[2] = ornt[2]; 3441 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3442 orntNew[3] = ornt[3]; 3443 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3444 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3445 #if 1 3446 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); 3447 for (p = 0; p < 4; ++p) { 3448 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 3449 } 3450 #endif 3451 /* D tetrahedron: {d, e, f, 3} */ 3452 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3453 orntNew[0] = 0; 3454 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3455 orntNew[1] = ornt[1]; 3456 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3457 orntNew[2] = ornt[2]; 3458 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3459 orntNew[3] = ornt[3]; 3460 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3461 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3462 #if 1 3463 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); 3464 for (p = 0; p < 4; ++p) { 3465 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 3466 } 3467 #endif 3468 /* A' tetrahedron: {d, a, c, f} */ 3469 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3470 orntNew[0] = -3; 3471 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3472 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3473 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3474 orntNew[2] = 0; 3475 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3476 orntNew[3] = 2; 3477 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3478 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3479 #if 1 3480 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); 3481 for (p = 0; p < 4; ++p) { 3482 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); 3483 } 3484 #endif 3485 /* B' tetrahedron: {e, b, a, f} */ 3486 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3487 orntNew[0] = -3; 3488 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3489 orntNew[1] = 1; 3490 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3491 orntNew[2] = 0; 3492 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 3493 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 3494 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3495 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3496 #if 1 3497 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); 3498 for (p = 0; p < 4; ++p) { 3499 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); 3500 } 3501 #endif 3502 /* C' tetrahedron: {b, f, c, a} */ 3503 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3504 orntNew[0] = -3; 3505 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 3506 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3507 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3508 orntNew[2] = -3; 3509 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3510 orntNew[3] = -2; 3511 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3512 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3513 #if 1 3514 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); 3515 for (p = 0; p < 4; ++p) { 3516 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); 3517 } 3518 #endif 3519 /* D' tetrahedron: {f, e, d, a} */ 3520 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3521 orntNew[0] = -3; 3522 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3523 orntNew[1] = -3; 3524 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 3525 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 3526 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3527 orntNew[3] = -3; 3528 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3529 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3530 #if 1 3531 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); 3532 for (p = 0; p < 4; ++p) { 3533 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); 3534 } 3535 #endif 3536 } 3537 /* Hybrid cells have 5 faces */ 3538 for (c = cMax; c < cEnd; ++c) { 3539 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 3540 const PetscInt *cone, *ornt, *fornt; 3541 PetscInt coneNew[5], orntNew[5], o, of, i; 3542 3543 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3544 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3545 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 3546 o = ornt[0] < 0 ? -1 : 1; 3547 for (r = 0; r < 3; ++r) { 3548 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 3549 orntNew[0] = ornt[0]; 3550 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 3551 orntNew[1] = ornt[1]; 3552 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 3553 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 3554 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 3555 orntNew[i] = 0; 3556 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 3557 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 3558 orntNew[i] = 0; 3559 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 3560 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 3561 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); 3562 orntNew[i] = 0; 3563 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3564 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3565 #if 1 3566 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); 3567 for (p = 0; p < 2; ++p) { 3568 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); 3569 } 3570 for (p = 2; p < 5; ++p) { 3571 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); 3572 } 3573 #endif 3574 } 3575 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 3576 orntNew[0] = 0; 3577 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3578 orntNew[1] = 0; 3579 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3580 orntNew[2] = 0; 3581 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3582 orntNew[3] = 0; 3583 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3584 orntNew[4] = 0; 3585 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3586 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3587 #if 1 3588 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); 3589 for (p = 0; p < 2; ++p) { 3590 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); 3591 } 3592 for (p = 2; p < 5; ++p) { 3593 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); 3594 } 3595 #endif 3596 } 3597 /* Split faces have 3 edges and the same cells as the parent */ 3598 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3599 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3600 for (f = fStart; f < fMax; ++f) { 3601 const PetscInt newp = fStartNew + (f - fStart)*4; 3602 const PetscInt *cone, *ornt, *support; 3603 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3604 3605 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3606 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3607 /* A triangle */ 3608 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3609 orntNew[0] = ornt[0]; 3610 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3611 orntNew[1] = -2; 3612 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3613 orntNew[2] = ornt[2]; 3614 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3615 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3616 #if 1 3617 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); 3618 for (p = 0; p < 3; ++p) { 3619 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); 3620 } 3621 #endif 3622 /* B triangle */ 3623 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3624 orntNew[0] = ornt[0]; 3625 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3626 orntNew[1] = ornt[1]; 3627 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3628 orntNew[2] = -2; 3629 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3630 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3631 #if 1 3632 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); 3633 for (p = 0; p < 3; ++p) { 3634 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); 3635 } 3636 #endif 3637 /* C triangle */ 3638 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3639 orntNew[0] = -2; 3640 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3641 orntNew[1] = ornt[1]; 3642 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3643 orntNew[2] = ornt[2]; 3644 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3645 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3646 #if 1 3647 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); 3648 for (p = 0; p < 3; ++p) { 3649 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); 3650 } 3651 #endif 3652 /* D triangle */ 3653 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3654 orntNew[0] = 0; 3655 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3656 orntNew[1] = 0; 3657 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3658 orntNew[2] = 0; 3659 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3660 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3661 #if 1 3662 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); 3663 for (p = 0; p < 3; ++p) { 3664 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); 3665 } 3666 #endif 3667 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3668 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3669 for (r = 0; r < 4; ++r) { 3670 for (s = 0; s < supportSize; ++s) { 3671 PetscInt subf; 3672 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3673 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3674 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3675 for (c = 0; c < coneSize; ++c) { 3676 if (cone[c] == f) break; 3677 } 3678 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3679 if (support[s] < cMax) { 3680 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3681 } else { 3682 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3683 } 3684 } 3685 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3686 #if 1 3687 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); 3688 for (p = 0; p < supportSize; ++p) { 3689 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); 3690 } 3691 #endif 3692 } 3693 } 3694 /* Interior cell faces have 3 edges and 2 cells */ 3695 for (c = cStart; c < cMax; ++c) { 3696 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3697 const PetscInt *cone, *ornt; 3698 PetscInt coneNew[3], orntNew[3]; 3699 PetscInt supportNew[2]; 3700 3701 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3702 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3703 /* Face A: {c, a, d} */ 3704 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3705 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3706 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3707 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3708 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3709 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3710 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3711 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3712 #if 1 3713 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3714 for (p = 0; p < 3; ++p) { 3715 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); 3716 } 3717 #endif 3718 supportNew[0] = (c - cStart)*8 + 0; 3719 supportNew[1] = (c - cStart)*8 + 0+4; 3720 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3721 #if 1 3722 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3723 for (p = 0; p < 2; ++p) { 3724 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); 3725 } 3726 #endif 3727 ++newp; 3728 /* Face B: {a, b, e} */ 3729 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3730 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3731 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3732 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3733 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3734 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3735 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3736 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3737 #if 1 3738 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); 3739 for (p = 0; p < 3; ++p) { 3740 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); 3741 } 3742 #endif 3743 supportNew[0] = (c - cStart)*8 + 1; 3744 supportNew[1] = (c - cStart)*8 + 1+4; 3745 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3746 #if 1 3747 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3748 for (p = 0; p < 2; ++p) { 3749 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); 3750 } 3751 #endif 3752 ++newp; 3753 /* Face C: {c, f, b} */ 3754 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3755 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3756 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3757 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3758 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3759 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3760 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3761 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3762 #if 1 3763 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3764 for (p = 0; p < 3; ++p) { 3765 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); 3766 } 3767 #endif 3768 supportNew[0] = (c - cStart)*8 + 2; 3769 supportNew[1] = (c - cStart)*8 + 2+4; 3770 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3771 #if 1 3772 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3773 for (p = 0; p < 2; ++p) { 3774 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); 3775 } 3776 #endif 3777 ++newp; 3778 /* Face D: {d, e, f} */ 3779 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3780 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3781 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3782 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3783 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3784 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3785 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3786 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3787 #if 1 3788 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3789 for (p = 0; p < 3; ++p) { 3790 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); 3791 } 3792 #endif 3793 supportNew[0] = (c - cStart)*8 + 3; 3794 supportNew[1] = (c - cStart)*8 + 3+4; 3795 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3796 #if 1 3797 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3798 for (p = 0; p < 2; ++p) { 3799 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); 3800 } 3801 #endif 3802 ++newp; 3803 /* Face E: {d, f, a} */ 3804 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3805 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3806 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3807 orntNew[1] = -2; 3808 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3809 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3810 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3811 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3812 #if 1 3813 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3814 for (p = 0; p < 3; ++p) { 3815 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); 3816 } 3817 #endif 3818 supportNew[0] = (c - cStart)*8 + 0+4; 3819 supportNew[1] = (c - cStart)*8 + 3+4; 3820 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3821 #if 1 3822 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3823 for (p = 0; p < 2; ++p) { 3824 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); 3825 } 3826 #endif 3827 ++newp; 3828 /* Face F: {c, a, f} */ 3829 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3830 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3831 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3832 orntNew[1] = 0; 3833 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3834 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3835 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3836 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3837 #if 1 3838 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3839 for (p = 0; p < 3; ++p) { 3840 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); 3841 } 3842 #endif 3843 supportNew[0] = (c - cStart)*8 + 0+4; 3844 supportNew[1] = (c - cStart)*8 + 2+4; 3845 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3846 #if 1 3847 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3848 for (p = 0; p < 2; ++p) { 3849 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); 3850 } 3851 #endif 3852 ++newp; 3853 /* Face G: {e, a, f} */ 3854 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3855 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3856 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3857 orntNew[1] = 0; 3858 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3859 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3860 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3861 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3862 #if 1 3863 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3864 for (p = 0; p < 3; ++p) { 3865 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); 3866 } 3867 #endif 3868 supportNew[0] = (c - cStart)*8 + 1+4; 3869 supportNew[1] = (c - cStart)*8 + 3+4; 3870 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3871 #if 1 3872 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3873 for (p = 0; p < 2; ++p) { 3874 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); 3875 } 3876 #endif 3877 ++newp; 3878 /* Face H: {a, b, f} */ 3879 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3880 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3881 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3882 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3883 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3884 orntNew[2] = -2; 3885 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3886 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3887 #if 1 3888 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3889 for (p = 0; p < 3; ++p) { 3890 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); 3891 } 3892 #endif 3893 supportNew[0] = (c - cStart)*8 + 1+4; 3894 supportNew[1] = (c - cStart)*8 + 2+4; 3895 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3896 #if 1 3897 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3898 for (p = 0; p < 2; ++p) { 3899 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); 3900 } 3901 #endif 3902 ++newp; 3903 } 3904 /* Hybrid split faces have 4 edges and same cells */ 3905 for (f = fMax; f < fEnd; ++f) { 3906 const PetscInt *cone, *ornt, *support; 3907 PetscInt coneNew[4], orntNew[4]; 3908 PetscInt supportNew[2], size, s, c; 3909 3910 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3911 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3912 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3913 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3914 for (r = 0; r < 2; ++r) { 3915 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3916 3917 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3918 orntNew[0] = ornt[0]; 3919 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3920 orntNew[1] = ornt[1]; 3921 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3922 orntNew[2+r] = 0; 3923 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3924 orntNew[3-r] = 0; 3925 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3926 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3927 #if 1 3928 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3929 for (p = 0; p < 2; ++p) { 3930 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); 3931 } 3932 for (p = 2; p < 4; ++p) { 3933 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); 3934 } 3935 #endif 3936 for (s = 0; s < size; ++s) { 3937 const PetscInt *coneCell, *orntCell, *fornt; 3938 PetscInt o, of; 3939 3940 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3941 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3942 o = orntCell[0] < 0 ? -1 : 1; 3943 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3944 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3945 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3946 of = fornt[c-2] < 0 ? -1 : 1; 3947 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3948 } 3949 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3950 #if 1 3951 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3952 for (p = 0; p < size; ++p) { 3953 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); 3954 } 3955 #endif 3956 } 3957 } 3958 /* Hybrid cell faces have 4 edges and 2 cells */ 3959 for (c = cMax; c < cEnd; ++c) { 3960 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3961 const PetscInt *cone, *ornt; 3962 PetscInt coneNew[4], orntNew[4]; 3963 PetscInt supportNew[2]; 3964 3965 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3966 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3967 for (r = 0; r < 3; ++r) { 3968 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3969 orntNew[0] = 0; 3970 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3971 orntNew[1] = 0; 3972 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3973 orntNew[2] = 0; 3974 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3975 orntNew[3] = 0; 3976 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3977 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3978 #if 1 3979 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); 3980 for (p = 0; p < 2; ++p) { 3981 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); 3982 } 3983 for (p = 2; p < 4; ++p) { 3984 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); 3985 } 3986 #endif 3987 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 3988 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 3989 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 3990 #if 1 3991 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); 3992 for (p = 0; p < 2; ++p) { 3993 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); 3994 } 3995 #endif 3996 } 3997 } 3998 /* Interior split edges have 2 vertices and the same faces as the parent */ 3999 for (e = eStart; e < eMax; ++e) { 4000 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4001 4002 for (r = 0; r < 2; ++r) { 4003 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4004 const PetscInt *cone, *ornt, *support; 4005 PetscInt coneNew[2], coneSize, c, supportSize, s; 4006 4007 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4008 coneNew[0] = vStartNew + (cone[0] - vStart); 4009 coneNew[1] = vStartNew + (cone[1] - vStart); 4010 coneNew[(r+1)%2] = newv; 4011 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4012 #if 1 4013 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4014 for (p = 0; p < 2; ++p) { 4015 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); 4016 } 4017 #endif 4018 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4019 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4020 for (s = 0; s < supportSize; ++s) { 4021 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4022 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4023 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4024 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 4025 if (support[s] < fMax) { 4026 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4027 } else { 4028 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4029 } 4030 } 4031 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4032 #if 1 4033 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4034 for (p = 0; p < supportSize; ++p) { 4035 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); 4036 } 4037 #endif 4038 } 4039 } 4040 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 4041 for (f = fStart; f < fMax; ++f) { 4042 const PetscInt *cone, *ornt, *support; 4043 PetscInt coneSize, supportSize, s; 4044 4045 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4046 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4047 for (r = 0; r < 3; ++r) { 4048 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 4049 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 4050 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 4051 -1, -1, 1, 6, 0, 4, 4052 2, 5, 3, 4, -1, -1, 4053 -1, -1, 3, 6, 2, 7}; 4054 4055 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4056 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4057 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4058 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4059 #if 1 4060 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4061 for (p = 0; p < 2; ++p) { 4062 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); 4063 } 4064 #endif 4065 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4066 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4067 for (s = 0; s < supportSize; ++s) { 4068 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4069 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4070 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4071 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4072 if (support[s] < cMax) { 4073 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4074 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4075 if (er == eint[c]) { 4076 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4077 } else { 4078 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4079 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4080 } 4081 } else { 4082 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4083 } 4084 } 4085 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4086 #if 1 4087 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4088 for (p = 0; p < intFaces; ++p) { 4089 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); 4090 } 4091 #endif 4092 } 4093 } 4094 /* Interior cell edges have 2 vertices and 4 faces */ 4095 for (c = cStart; c < cMax; ++c) { 4096 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4097 const PetscInt *cone, *ornt, *fcone; 4098 PetscInt coneNew[2], supportNew[4], find; 4099 4100 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4101 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4102 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4103 find = GetTriEdge_Static(ornt[0], 0); 4104 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4105 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4106 find = GetTriEdge_Static(ornt[2], 1); 4107 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4108 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4109 #if 1 4110 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4111 for (p = 0; p < 2; ++p) { 4112 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 4113 } 4114 #endif 4115 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4116 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4117 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4118 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4119 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4120 #if 1 4121 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4122 for (p = 0; p < 4; ++p) { 4123 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); 4124 } 4125 #endif 4126 } 4127 /* Hybrid edges have two vertices and the same faces */ 4128 for (e = eMax; e < eEnd; ++e) { 4129 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4130 const PetscInt *cone, *support, *fcone; 4131 PetscInt coneNew[2], size, fsize, s; 4132 4133 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4134 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4135 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4136 coneNew[0] = vStartNew + (cone[0] - vStart); 4137 coneNew[1] = vStartNew + (cone[1] - vStart); 4138 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4139 #if 1 4140 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4141 for (p = 0; p < 2; ++p) { 4142 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); 4143 } 4144 #endif 4145 for (s = 0; s < size; ++s) { 4146 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4147 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4148 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4149 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 4150 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4151 } 4152 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4153 #if 1 4154 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4155 for (p = 0; p < size; ++p) { 4156 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); 4157 } 4158 #endif 4159 } 4160 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4161 for (f = fMax; f < fEnd; ++f) { 4162 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4163 const PetscInt *cone, *support, *ccone, *cornt; 4164 PetscInt coneNew[2], size, csize, s; 4165 4166 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4167 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4168 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4169 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4170 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4171 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4172 #if 1 4173 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4174 for (p = 0; p < 2; ++p) { 4175 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); 4176 } 4177 #endif 4178 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4179 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4180 for (s = 0; s < size; ++s) { 4181 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4182 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4183 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4184 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4185 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]); 4186 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4187 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4188 } 4189 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4190 #if 1 4191 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4192 for (p = 0; p < 2+size*2; ++p) { 4193 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); 4194 } 4195 #endif 4196 } 4197 /* Interior vertices have identical supports */ 4198 for (v = vStart; v < vEnd; ++v) { 4199 const PetscInt newp = vStartNew + (v - vStart); 4200 const PetscInt *support, *cone; 4201 PetscInt size, s; 4202 4203 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4204 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4205 for (s = 0; s < size; ++s) { 4206 PetscInt r = 0; 4207 4208 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4209 if (cone[1] == v) r = 1; 4210 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4211 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4212 } 4213 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4214 #if 1 4215 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4216 for (p = 0; p < size; ++p) { 4217 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); 4218 } 4219 #endif 4220 } 4221 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4222 for (e = eStart; e < eMax; ++e) { 4223 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4224 const PetscInt *cone, *support; 4225 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4226 4227 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4228 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4229 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4230 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4231 for (s = 0; s < size; ++s) { 4232 PetscInt r = 0; 4233 4234 if (support[s] < fMax) { 4235 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4236 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4237 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4238 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4239 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4240 faceSize += 2; 4241 } else { 4242 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4243 ++faceSize; 4244 } 4245 } 4246 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4247 for (s = 0; s < starSize*2; s += 2) { 4248 const PetscInt *cone, *ornt; 4249 PetscInt e01, e23; 4250 4251 if ((star[s] >= cStart) && (star[s] < cMax)) { 4252 /* Check edge 0-1 */ 4253 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4254 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4255 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4256 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4257 /* Check edge 2-3 */ 4258 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4259 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4260 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4261 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4262 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 4263 } 4264 } 4265 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4266 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4267 #if 1 4268 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4269 for (p = 0; p < 2+faceSize+cellSize; ++p) { 4270 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); 4271 } 4272 #endif 4273 } 4274 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4275 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4276 break; 4277 case REFINER_SIMPLEX_TO_HEX_3D: 4278 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4279 /* All cells have 6 faces */ 4280 for (c = cStart; c < cEnd; ++c) { 4281 const PetscInt newp = cStartNew + (c - cStart)*4; 4282 const PetscInt *cone, *ornt; 4283 PetscInt coneNew[6]; 4284 PetscInt orntNew[6]; 4285 4286 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4287 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4288 /* A hex */ 4289 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 4290 orntNew[0] = ornt[0] < 0 ? -1 : 1; 4291 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 4292 orntNew[1] = -4; 4293 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 4294 orntNew[2] = ornt[2] < 0 ? -1 : 1; 4295 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 4296 orntNew[3] = -1; 4297 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 4298 orntNew[4] = 0; 4299 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 4300 orntNew[5] = ornt[1] < 0 ? -1 : 1; 4301 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4302 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4303 #if 1 4304 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); 4305 for (p = 0; p < 6; ++p) { 4306 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4307 } 4308 #endif 4309 /* B hex */ 4310 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 4311 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4312 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 4313 orntNew[1] = 0; 4314 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 4315 orntNew[2] = 0; 4316 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 4317 orntNew[3] = ornt[3] < 0 ? -2 : 0; 4318 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 4319 orntNew[4] = 0; 4320 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 4321 orntNew[5] = ornt[1] < 0 ? -4 : 2; 4322 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4323 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4324 #if 1 4325 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); 4326 for (p = 0; p < 6; ++p) { 4327 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); 4328 } 4329 #endif 4330 /* C hex */ 4331 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 4332 orntNew[0] = ornt[0] < 0 ? -4 : 2; 4333 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 4334 orntNew[1] = -4; 4335 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 4336 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4337 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 4338 orntNew[3] = -1; 4339 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 4340 orntNew[4] = ornt[3] < 0 ? -1 : 1; 4341 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 4342 orntNew[5] = -4; 4343 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4344 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4345 #if 1 4346 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); 4347 for (p = 0; p < 6; ++p) { 4348 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); 4349 } 4350 #endif 4351 /* D hex */ 4352 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 4353 orntNew[0] = 0; 4354 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 4355 orntNew[1] = ornt[3] < 0 ? -1 : 1; 4356 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 4357 orntNew[2] = ornt[2] < 0 ? -4 : 2; 4358 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 4359 orntNew[3] = -1; 4360 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 4361 orntNew[4] = 0; 4362 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 4363 orntNew[5] = ornt[1] < 0 ? -2 : 0; 4364 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4365 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4366 #if 1 4367 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); 4368 for (p = 0; p < 6; ++p) { 4369 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); 4370 } 4371 #endif 4372 } 4373 /* Split faces have 4 edges and the same cells as the parent */ 4374 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4375 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4376 for (f = fStart; f < fEnd; ++f) { 4377 const PetscInt newp = fStartNew + (f - fStart)*3; 4378 const PetscInt *cone, *ornt, *support; 4379 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 4380 4381 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4382 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4383 /* A quad */ 4384 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4385 orntNew[0] = ornt[2]; 4386 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4387 orntNew[1] = ornt[0]; 4388 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4389 orntNew[2] = 0; 4390 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4391 orntNew[3] = -2; 4392 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4393 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4394 #if 1 4395 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); 4396 for (p = 0; p < 4; ++p) { 4397 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); 4398 } 4399 #endif 4400 /* B quad */ 4401 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4402 orntNew[0] = ornt[0]; 4403 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4404 orntNew[1] = ornt[1]; 4405 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4406 orntNew[2] = 0; 4407 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4408 orntNew[3] = -2; 4409 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4410 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4411 #if 1 4412 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); 4413 for (p = 0; p < 4; ++p) { 4414 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); 4415 } 4416 #endif 4417 /* C quad */ 4418 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4419 orntNew[0] = ornt[1]; 4420 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4421 orntNew[1] = ornt[2]; 4422 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4423 orntNew[2] = 0; 4424 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4425 orntNew[3] = -2; 4426 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4427 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4428 #if 1 4429 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); 4430 for (p = 0; p < 4; ++p) { 4431 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); 4432 } 4433 #endif 4434 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4435 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4436 for (r = 0; r < 3; ++r) { 4437 for (s = 0; s < supportSize; ++s) { 4438 PetscInt subf; 4439 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4440 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4441 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4442 for (c = 0; c < coneSize; ++c) { 4443 if (cone[c] == f) break; 4444 } 4445 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4446 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 4447 } 4448 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4449 #if 1 4450 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); 4451 for (p = 0; p < supportSize; ++p) { 4452 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); 4453 } 4454 #endif 4455 } 4456 } 4457 /* Interior faces have 4 edges and 2 cells */ 4458 for (c = cStart; c < cEnd; ++c) { 4459 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 4460 const PetscInt *cone, *ornt; 4461 PetscInt coneNew[4], orntNew[4]; 4462 PetscInt supportNew[2]; 4463 4464 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4465 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4466 /* Face {a, g, m, h} */ 4467 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 4468 orntNew[0] = 0; 4469 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4470 orntNew[1] = 0; 4471 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4472 orntNew[2] = -2; 4473 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 4474 orntNew[3] = -2; 4475 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4476 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4477 #if 1 4478 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4479 for (p = 0; p < 4; ++p) { 4480 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); 4481 } 4482 #endif 4483 supportNew[0] = (c - cStart)*4 + 0; 4484 supportNew[1] = (c - cStart)*4 + 1; 4485 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4486 #if 1 4487 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4488 for (p = 0; p < 2; ++p) { 4489 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); 4490 } 4491 #endif 4492 ++newp; 4493 /* Face {g, b, l , m} */ 4494 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 4495 orntNew[0] = -2; 4496 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 4497 orntNew[1] = 0; 4498 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4499 orntNew[2] = 0; 4500 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4501 orntNew[3] = -2; 4502 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4503 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4504 #if 1 4505 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4506 for (p = 0; p < 4; ++p) { 4507 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); 4508 } 4509 #endif 4510 supportNew[0] = (c - cStart)*4 + 1; 4511 supportNew[1] = (c - cStart)*4 + 2; 4512 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4513 #if 1 4514 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4515 for (p = 0; p < 2; ++p) { 4516 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); 4517 } 4518 #endif 4519 ++newp; 4520 /* Face {c, g, m, i} */ 4521 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 4522 orntNew[0] = 0; 4523 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4524 orntNew[1] = 0; 4525 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4526 orntNew[2] = -2; 4527 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 4528 orntNew[3] = -2; 4529 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4530 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4531 #if 1 4532 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4533 for (p = 0; p < 4; ++p) { 4534 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); 4535 } 4536 #endif 4537 supportNew[0] = (c - cStart)*4 + 0; 4538 supportNew[1] = (c - cStart)*4 + 2; 4539 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4540 #if 1 4541 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4542 for (p = 0; p < 2; ++p) { 4543 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); 4544 } 4545 #endif 4546 ++newp; 4547 /* Face {d, h, m, i} */ 4548 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 4549 orntNew[0] = 0; 4550 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4551 orntNew[1] = 0; 4552 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4553 orntNew[2] = -2; 4554 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 4555 orntNew[3] = -2; 4556 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4557 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4558 #if 1 4559 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4560 for (p = 0; p < 4; ++p) { 4561 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); 4562 } 4563 #endif 4564 supportNew[0] = (c - cStart)*4 + 0; 4565 supportNew[1] = (c - cStart)*4 + 3; 4566 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4567 #if 1 4568 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4569 for (p = 0; p < 2; ++p) { 4570 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); 4571 } 4572 #endif 4573 ++newp; 4574 /* Face {h, m, l, e} */ 4575 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4576 orntNew[0] = 0; 4577 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4578 orntNew[1] = -2; 4579 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 4580 orntNew[2] = -2; 4581 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 4582 orntNew[3] = 0; 4583 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4584 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4585 #if 1 4586 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4587 for (p = 0; p < 4; ++p) { 4588 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); 4589 } 4590 #endif 4591 supportNew[0] = (c - cStart)*4 + 1; 4592 supportNew[1] = (c - cStart)*4 + 3; 4593 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4594 #if 1 4595 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4596 for (p = 0; p < 2; ++p) { 4597 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); 4598 } 4599 #endif 4600 ++newp; 4601 /* Face {i, m, l, f} */ 4602 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4603 orntNew[0] = 0; 4604 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4605 orntNew[1] = -2; 4606 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 4607 orntNew[2] = -2; 4608 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 4609 orntNew[3] = 0; 4610 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4611 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4612 #if 1 4613 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4614 for (p = 0; p < 4; ++p) { 4615 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); 4616 } 4617 #endif 4618 supportNew[0] = (c - cStart)*4 + 2; 4619 supportNew[1] = (c - cStart)*4 + 3; 4620 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4621 #if 1 4622 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4623 for (p = 0; p < 2; ++p) { 4624 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); 4625 } 4626 #endif 4627 ++newp; 4628 } 4629 /* Split Edges have 2 vertices and the same faces as the parent */ 4630 for (e = eStart; e < eEnd; ++e) { 4631 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4632 4633 for (r = 0; r < 2; ++r) { 4634 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4635 const PetscInt *cone, *ornt, *support; 4636 PetscInt coneNew[2], coneSize, c, supportSize, s; 4637 4638 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4639 coneNew[0] = vStartNew + (cone[0] - vStart); 4640 coneNew[1] = vStartNew + (cone[1] - vStart); 4641 coneNew[(r+1)%2] = newv; 4642 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4643 #if 1 4644 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4645 for (p = 0; p < 2; ++p) { 4646 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); 4647 } 4648 #endif 4649 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4650 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4651 for (s = 0; s < supportSize; ++s) { 4652 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4653 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4654 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4655 for (c = 0; c < coneSize; ++c) { 4656 if (cone[c] == e) break; 4657 } 4658 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4659 } 4660 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4661 #if 1 4662 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4663 for (p = 0; p < supportSize; ++p) { 4664 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); 4665 } 4666 #endif 4667 } 4668 } 4669 /* Face edges have 2 vertices and 2 + cell faces supports */ 4670 for (f = fStart; f < fEnd; ++f) { 4671 const PetscInt *cone, *ornt, *support; 4672 PetscInt coneSize, supportSize, s; 4673 4674 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4675 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4676 for (r = 0; r < 3; ++r) { 4677 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 4678 PetscInt coneNew[2]; 4679 PetscInt fint[4][3] = { {0, 1, 2}, 4680 {3, 4, 0}, 4681 {2, 5, 3}, 4682 {1, 4, 5} }; 4683 4684 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4685 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4686 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 4687 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4688 #if 1 4689 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4690 for (p = 0; p < 2; ++p) { 4691 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); 4692 } 4693 #endif 4694 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 4695 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 4696 for (s = 0; s < supportSize; ++s) { 4697 PetscInt er; 4698 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4699 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4700 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4701 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4702 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 4703 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 4704 } 4705 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4706 #if 1 4707 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4708 for (p = 0; p < supportSize + 2; ++p) { 4709 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); 4710 } 4711 #endif 4712 } 4713 } 4714 /* Interior cell edges have 2 vertices and 3 faces */ 4715 for (c = cStart; c < cEnd; ++c) { 4716 const PetscInt *cone; 4717 PetscInt fint[4][3] = { {0,1,2}, 4718 {0,3,4}, 4719 {2,3,5}, 4720 {1,4,5} } ; 4721 4722 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4723 for (r = 0; r < 4; r++) { 4724 PetscInt coneNew[2], supportNew[3]; 4725 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 4726 4727 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4728 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 4729 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4730 #if 1 4731 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4732 for (p = 0; p < 2; ++p) { 4733 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); 4734 } 4735 #endif 4736 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 4737 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 4738 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 4739 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4740 #if 1 4741 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4742 for (p = 0; p < 3; ++p) { 4743 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); 4744 } 4745 #endif 4746 } 4747 } 4748 /* Old vertices have identical supports */ 4749 for (v = vStart; v < vEnd; ++v) { 4750 const PetscInt newp = vStartNew + (v - vStart); 4751 const PetscInt *support, *cone; 4752 PetscInt size, s; 4753 4754 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4755 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4756 for (s = 0; s < size; ++s) { 4757 PetscInt r = 0; 4758 4759 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4760 if (cone[1] == v) r = 1; 4761 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4762 } 4763 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4764 #if 1 4765 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4766 for (p = 0; p < size; ++p) { 4767 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 4768 } 4769 #endif 4770 } 4771 /* Edge vertices have 2 + faces supports */ 4772 for (e = eStart; e < eEnd; ++e) { 4773 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4774 const PetscInt *cone, *support; 4775 PetscInt size, s; 4776 4777 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4778 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4779 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4780 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4781 for (s = 0; s < size; ++s) { 4782 PetscInt r = 0, coneSize; 4783 4784 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4785 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4786 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4787 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 4788 } 4789 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4790 #if 1 4791 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4792 for (p = 0; p < 2+size; ++p) { 4793 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); 4794 } 4795 #endif 4796 } 4797 /* Face vertices have 3 + cells supports */ 4798 for (f = fStart; f < fEnd; ++f) { 4799 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4800 const PetscInt *cone, *support; 4801 PetscInt size, s; 4802 4803 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4804 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4805 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4806 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4807 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4808 for (s = 0; s < size; ++s) { 4809 PetscInt r = 0, coneSize; 4810 4811 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4812 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4813 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 4814 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 4815 } 4816 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4817 #if 1 4818 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4819 for (p = 0; p < 3+size; ++p) { 4820 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); 4821 } 4822 #endif 4823 } 4824 /* Interior cell vertices have 4 supports */ 4825 for (c = cStart; c < cEnd; ++c) { 4826 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 4827 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4828 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4829 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4830 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4831 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4832 #if 1 4833 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4834 for (p = 0; p < 4; ++p) { 4835 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); 4836 } 4837 #endif 4838 } 4839 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4840 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4841 break; 4842 case REFINER_HEX_3D: 4843 /* 4844 Bottom (viewed from top) Top 4845 1---------2---------2 7---------2---------6 4846 | | | | | | 4847 | B 2 C | | H 2 G | 4848 | | | | | | 4849 3----3----0----1----1 3----3----0----1----1 4850 | | | | | | 4851 | A 0 D | | E 0 F | 4852 | | | | | | 4853 0---------0---------3 4---------0---------5 4854 */ 4855 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4856 for (c = cStart; c < cEnd; ++c) { 4857 const PetscInt newp = (c - cStart)*8; 4858 const PetscInt *cone, *ornt; 4859 PetscInt coneNew[6], orntNew[6]; 4860 4861 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4862 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4863 /* A hex */ 4864 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4865 orntNew[0] = ornt[0]; 4866 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4867 orntNew[1] = 0; 4868 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4869 orntNew[2] = ornt[2]; 4870 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4871 orntNew[3] = 0; 4872 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4873 orntNew[4] = 0; 4874 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4875 orntNew[5] = ornt[5]; 4876 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4877 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4878 #if 1 4879 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); 4880 for (p = 0; p < 6; ++p) { 4881 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4882 } 4883 #endif 4884 /* B hex */ 4885 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4886 orntNew[0] = ornt[0]; 4887 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4888 orntNew[1] = 0; 4889 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4890 orntNew[2] = -1; 4891 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4892 orntNew[3] = ornt[3]; 4893 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4894 orntNew[4] = 0; 4895 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4896 orntNew[5] = ornt[5]; 4897 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4898 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4899 #if 1 4900 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); 4901 for (p = 0; p < 6; ++p) { 4902 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4903 } 4904 #endif 4905 /* C hex */ 4906 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4907 orntNew[0] = ornt[0]; 4908 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4909 orntNew[1] = 0; 4910 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4911 orntNew[2] = -1; 4912 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4913 orntNew[3] = ornt[3]; 4914 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4915 orntNew[4] = ornt[4]; 4916 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4917 orntNew[5] = -4; 4918 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4919 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4920 #if 1 4921 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); 4922 for (p = 0; p < 6; ++p) { 4923 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4924 } 4925 #endif 4926 /* D hex */ 4927 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4928 orntNew[0] = ornt[0]; 4929 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4930 orntNew[1] = 0; 4931 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4932 orntNew[2] = ornt[2]; 4933 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4934 orntNew[3] = 0; 4935 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4936 orntNew[4] = ornt[4]; 4937 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4938 orntNew[5] = -4; 4939 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4940 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4941 #if 1 4942 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); 4943 for (p = 0; p < 6; ++p) { 4944 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4945 } 4946 #endif 4947 /* E hex */ 4948 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4949 orntNew[0] = -4; 4950 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4951 orntNew[1] = ornt[1]; 4952 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4953 orntNew[2] = ornt[2]; 4954 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4955 orntNew[3] = 0; 4956 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4957 orntNew[4] = -1; 4958 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4959 orntNew[5] = ornt[5]; 4960 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4961 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4962 #if 1 4963 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); 4964 for (p = 0; p < 6; ++p) { 4965 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4966 } 4967 #endif 4968 /* F hex */ 4969 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4970 orntNew[0] = -4; 4971 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4972 orntNew[1] = ornt[1]; 4973 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4974 orntNew[2] = ornt[2]; 4975 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4976 orntNew[3] = -1; 4977 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 4978 orntNew[4] = ornt[4]; 4979 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4980 orntNew[5] = 1; 4981 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4982 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4983 #if 1 4984 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); 4985 for (p = 0; p < 6; ++p) { 4986 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); 4987 } 4988 #endif 4989 /* G hex */ 4990 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4991 orntNew[0] = -4; 4992 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 4993 orntNew[1] = ornt[1]; 4994 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 4995 orntNew[2] = 0; 4996 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 4997 orntNew[3] = ornt[3]; 4998 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 4999 orntNew[4] = ornt[4]; 5000 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5001 orntNew[5] = -3; 5002 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 5003 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 5004 #if 1 5005 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); 5006 for (p = 0; p < 6; ++p) { 5007 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); 5008 } 5009 #endif 5010 /* H hex */ 5011 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5012 orntNew[0] = -4; 5013 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 5014 orntNew[1] = ornt[1]; 5015 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5016 orntNew[2] = -1; 5017 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 5018 orntNew[3] = ornt[3]; 5019 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5020 orntNew[4] = 3; 5021 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 5022 orntNew[5] = ornt[5]; 5023 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 5024 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 5025 #if 1 5026 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); 5027 for (p = 0; p < 6; ++p) { 5028 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); 5029 } 5030 #endif 5031 } 5032 /* Split faces have 4 edges and the same cells as the parent */ 5033 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5034 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5035 for (f = fStart; f < fEnd; ++f) { 5036 for (r = 0; r < 4; ++r) { 5037 /* TODO: This can come from GetFaces_Internal() */ 5038 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}; 5039 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 5040 const PetscInt *cone, *ornt, *support; 5041 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 5042 5043 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5044 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5045 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 5046 orntNew[(r+3)%4] = ornt[(r+3)%4]; 5047 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 5048 orntNew[(r+0)%4] = ornt[r]; 5049 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5050 orntNew[(r+1)%4] = 0; 5051 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 5052 orntNew[(r+2)%4] = -2; 5053 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5054 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5055 #if 1 5056 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5057 for (p = 0; p < 4; ++p) { 5058 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); 5059 } 5060 #endif 5061 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5062 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5063 for (s = 0; s < supportSize; ++s) { 5064 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5065 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5066 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5067 for (c = 0; c < coneSize; ++c) { 5068 if (cone[c] == f) break; 5069 } 5070 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 5071 } 5072 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5073 #if 1 5074 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5075 for (p = 0; p < supportSize; ++p) { 5076 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); 5077 } 5078 #endif 5079 } 5080 } 5081 /* Interior faces have 4 edges and 2 cells */ 5082 for (c = cStart; c < cEnd; ++c) { 5083 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}; 5084 const PetscInt *cone, *ornt; 5085 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 5086 5087 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5088 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5089 /* A-D face */ 5090 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 5091 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 5092 orntNew[0] = 0; 5093 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5094 orntNew[1] = 0; 5095 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5096 orntNew[2] = -2; 5097 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 5098 orntNew[3] = -2; 5099 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5100 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5101 #if 1 5102 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5103 for (p = 0; p < 4; ++p) { 5104 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); 5105 } 5106 #endif 5107 /* C-D face */ 5108 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 5109 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 5110 orntNew[0] = 0; 5111 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5112 orntNew[1] = 0; 5113 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5114 orntNew[2] = -2; 5115 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 5116 orntNew[3] = -2; 5117 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5118 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5119 #if 1 5120 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5121 for (p = 0; p < 4; ++p) { 5122 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); 5123 } 5124 #endif 5125 /* B-C face */ 5126 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 5127 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 5128 orntNew[0] = -2; 5129 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 5130 orntNew[1] = 0; 5131 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5132 orntNew[2] = 0; 5133 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5134 orntNew[3] = -2; 5135 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5136 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5137 #if 1 5138 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5139 for (p = 0; p < 4; ++p) { 5140 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); 5141 } 5142 #endif 5143 /* A-B face */ 5144 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 5145 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 5146 orntNew[0] = -2; 5147 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 5148 orntNew[1] = 0; 5149 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5150 orntNew[2] = 0; 5151 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5152 orntNew[3] = -2; 5153 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5154 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5155 #if 1 5156 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5157 for (p = 0; p < 4; ++p) { 5158 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); 5159 } 5160 #endif 5161 /* E-F face */ 5162 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 5163 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5164 orntNew[0] = -2; 5165 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 5166 orntNew[1] = -2; 5167 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 5168 orntNew[2] = 0; 5169 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5170 orntNew[3] = 0; 5171 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5172 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5173 #if 1 5174 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5175 for (p = 0; p < 4; ++p) { 5176 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); 5177 } 5178 #endif 5179 /* F-G face */ 5180 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 5181 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5182 orntNew[0] = -2; 5183 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 5184 orntNew[1] = -2; 5185 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 5186 orntNew[2] = 0; 5187 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5188 orntNew[3] = 0; 5189 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5190 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5191 #if 1 5192 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5193 for (p = 0; p < 4; ++p) { 5194 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); 5195 } 5196 #endif 5197 /* G-H face */ 5198 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 5199 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 5200 orntNew[0] = -2; 5201 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 5202 orntNew[1] = 0; 5203 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5204 orntNew[2] = 0; 5205 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5206 orntNew[3] = -2; 5207 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5208 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5209 #if 1 5210 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5211 for (p = 0; p < 4; ++p) { 5212 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); 5213 } 5214 #endif 5215 /* E-H face */ 5216 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 5217 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5218 orntNew[0] = -2; 5219 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 5220 orntNew[1] = -2; 5221 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 5222 orntNew[2] = 0; 5223 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5224 orntNew[3] = 0; 5225 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5226 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5227 #if 1 5228 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5229 for (p = 0; p < 4; ++p) { 5230 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); 5231 } 5232 #endif 5233 /* A-E face */ 5234 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 5235 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 5236 orntNew[0] = 0; 5237 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5238 orntNew[1] = 0; 5239 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5240 orntNew[2] = -2; 5241 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 5242 orntNew[3] = -2; 5243 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5244 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5245 #if 1 5246 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5247 for (p = 0; p < 4; ++p) { 5248 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); 5249 } 5250 #endif 5251 /* D-F face */ 5252 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 5253 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 5254 orntNew[0] = -2; 5255 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 5256 orntNew[1] = 0; 5257 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5258 orntNew[2] = 0; 5259 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5260 orntNew[3] = -2; 5261 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5262 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5263 #if 1 5264 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5265 for (p = 0; p < 4; ++p) { 5266 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); 5267 } 5268 #endif 5269 /* C-G face */ 5270 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 5271 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5272 orntNew[0] = -2; 5273 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 5274 orntNew[1] = -2; 5275 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 5276 orntNew[2] = 0; 5277 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5278 orntNew[3] = 0; 5279 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5280 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5281 #if 1 5282 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5283 for (p = 0; p < 4; ++p) { 5284 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); 5285 } 5286 #endif 5287 /* B-H face */ 5288 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 5289 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5290 orntNew[0] = 0; 5291 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5292 orntNew[1] = -2; 5293 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 5294 orntNew[2] = -2; 5295 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 5296 orntNew[3] = 0; 5297 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5298 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5299 #if 1 5300 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5301 for (p = 0; p < 4; ++p) { 5302 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); 5303 } 5304 #endif 5305 for (r = 0; r < 12; ++r) { 5306 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 5307 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 5308 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 5309 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5310 #if 1 5311 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5312 for (p = 0; p < 2; ++p) { 5313 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); 5314 } 5315 #endif 5316 } 5317 } 5318 /* Split edges have 2 vertices and the same faces as the parent */ 5319 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5320 for (e = eStart; e < eEnd; ++e) { 5321 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5322 5323 for (r = 0; r < 2; ++r) { 5324 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5325 const PetscInt *cone, *ornt, *support; 5326 PetscInt coneNew[2], coneSize, c, supportSize, s; 5327 5328 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5329 coneNew[0] = vStartNew + (cone[0] - vStart); 5330 coneNew[1] = vStartNew + (cone[1] - vStart); 5331 coneNew[(r+1)%2] = newv; 5332 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5333 #if 1 5334 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5335 for (p = 0; p < 2; ++p) { 5336 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); 5337 } 5338 #endif 5339 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5340 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5341 for (s = 0; s < supportSize; ++s) { 5342 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5343 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5344 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5345 for (c = 0; c < coneSize; ++c) { 5346 if (cone[c] == e) break; 5347 } 5348 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 5349 } 5350 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5351 #if 1 5352 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5353 for (p = 0; p < supportSize; ++p) { 5354 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); 5355 } 5356 #endif 5357 } 5358 } 5359 /* Face edges have 2 vertices and 2+cells faces */ 5360 for (f = fStart; f < fEnd; ++f) { 5361 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}; 5362 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5363 const PetscInt *cone, *coneCell, *orntCell, *support; 5364 PetscInt coneNew[2], coneSize, c, supportSize, s; 5365 5366 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5367 for (r = 0; r < 4; ++r) { 5368 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5369 5370 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5371 coneNew[1] = newv; 5372 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5373 #if 1 5374 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5375 for (p = 0; p < 2; ++p) { 5376 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); 5377 } 5378 #endif 5379 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5380 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5381 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5382 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5383 for (s = 0; s < supportSize; ++s) { 5384 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5385 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5386 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5387 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5388 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5389 } 5390 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5391 #if 1 5392 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5393 for (p = 0; p < 2+supportSize; ++p) { 5394 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); 5395 } 5396 #endif 5397 } 5398 } 5399 /* Cell edges have 2 vertices and 4 faces */ 5400 for (c = cStart; c < cEnd; ++c) { 5401 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}; 5402 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 5403 const PetscInt *cone; 5404 PetscInt coneNew[2], supportNew[4]; 5405 5406 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5407 for (r = 0; r < 6; ++r) { 5408 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 5409 5410 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5411 coneNew[1] = newv; 5412 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5413 #if 1 5414 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5415 for (p = 0; p < 2; ++p) { 5416 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); 5417 } 5418 #endif 5419 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5420 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5421 #if 1 5422 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5423 for (p = 0; p < 4; ++p) { 5424 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); 5425 } 5426 #endif 5427 } 5428 } 5429 /* Old vertices have identical supports */ 5430 for (v = vStart; v < vEnd; ++v) { 5431 const PetscInt newp = vStartNew + (v - vStart); 5432 const PetscInt *support, *cone; 5433 PetscInt size, s; 5434 5435 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5436 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5437 for (s = 0; s < size; ++s) { 5438 PetscInt r = 0; 5439 5440 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5441 if (cone[1] == v) r = 1; 5442 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5443 } 5444 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5445 #if 1 5446 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5447 for (p = 0; p < size; ++p) { 5448 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); 5449 } 5450 #endif 5451 } 5452 /* Edge vertices have 2 + faces supports */ 5453 for (e = eStart; e < eEnd; ++e) { 5454 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5455 const PetscInt *cone, *support; 5456 PetscInt size, s; 5457 5458 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5459 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5460 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5461 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5462 for (s = 0; s < size; ++s) { 5463 PetscInt r; 5464 5465 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5466 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 5467 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 5468 } 5469 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5470 #if 1 5471 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5472 for (p = 0; p < 2+size; ++p) { 5473 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); 5474 } 5475 #endif 5476 } 5477 /* Face vertices have 4 + cells supports */ 5478 for (f = fStart; f < fEnd; ++f) { 5479 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5480 const PetscInt *cone, *support; 5481 PetscInt size, s; 5482 5483 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5484 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5485 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5486 for (s = 0; s < size; ++s) { 5487 PetscInt r; 5488 5489 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5490 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5491 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 5492 } 5493 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5494 #if 1 5495 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5496 for (p = 0; p < 4+size; ++p) { 5497 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); 5498 } 5499 #endif 5500 } 5501 /* Cell vertices have 6 supports */ 5502 for (c = cStart; c < cEnd; ++c) { 5503 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 5504 PetscInt supportNew[6]; 5505 5506 for (r = 0; r < 6; ++r) { 5507 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 5508 } 5509 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5510 } 5511 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5512 break; 5513 case REFINER_HYBRID_HEX_3D: 5514 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 5515 /* 5516 Bottom (viewed from top) Top 5517 1---------2---------2 7---------2---------6 5518 | | | | | | 5519 | B 2 C | | H 2 G | 5520 | | | | | | 5521 3----3----0----1----1 3----3----0----1----1 5522 | | | | | | 5523 | A 0 D | | E 0 F | 5524 | | | | | | 5525 0---------0---------3 4---------0---------5 5526 */ 5527 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 5528 for (c = cStart; c < cMax; ++c) { 5529 const PetscInt newp = (c - cStart)*8; 5530 const PetscInt *cone, *ornt; 5531 PetscInt coneNew[6], orntNew[6]; 5532 5533 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5534 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5535 /* A hex */ 5536 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 5537 orntNew[0] = ornt[0]; 5538 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 5539 orntNew[1] = 0; 5540 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 5541 orntNew[2] = ornt[2]; 5542 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 5543 orntNew[3] = 0; 5544 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 5545 orntNew[4] = 0; 5546 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 5547 orntNew[5] = ornt[5]; 5548 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5549 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5550 #if 1 5551 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); 5552 for (p = 0; p < 6; ++p) { 5553 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 5554 } 5555 #endif 5556 /* B hex */ 5557 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 5558 orntNew[0] = ornt[0]; 5559 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5560 orntNew[1] = 0; 5561 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 5562 orntNew[2] = -1; 5563 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 5564 orntNew[3] = ornt[3]; 5565 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 5566 orntNew[4] = 0; 5567 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 5568 orntNew[5] = ornt[5]; 5569 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5570 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5571 #if 1 5572 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); 5573 for (p = 0; p < 6; ++p) { 5574 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 5575 } 5576 #endif 5577 /* C hex */ 5578 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 5579 orntNew[0] = ornt[0]; 5580 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 5581 orntNew[1] = 0; 5582 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 5583 orntNew[2] = -1; 5584 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 5585 orntNew[3] = ornt[3]; 5586 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 5587 orntNew[4] = ornt[4]; 5588 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 5589 orntNew[5] = -4; 5590 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5591 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5592 #if 1 5593 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); 5594 for (p = 0; p < 6; ++p) { 5595 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 5596 } 5597 #endif 5598 /* D hex */ 5599 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 5600 orntNew[0] = ornt[0]; 5601 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 5602 orntNew[1] = 0; 5603 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 5604 orntNew[2] = ornt[2]; 5605 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 5606 orntNew[3] = 0; 5607 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 5608 orntNew[4] = ornt[4]; 5609 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 5610 orntNew[5] = -4; 5611 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5612 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5613 #if 1 5614 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); 5615 for (p = 0; p < 6; ++p) { 5616 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 5617 } 5618 #endif 5619 /* E hex */ 5620 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 5621 orntNew[0] = -4; 5622 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 5623 orntNew[1] = ornt[1]; 5624 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 5625 orntNew[2] = ornt[2]; 5626 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5627 orntNew[3] = 0; 5628 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 5629 orntNew[4] = -1; 5630 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 5631 orntNew[5] = ornt[5]; 5632 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 5633 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 5634 #if 1 5635 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); 5636 for (p = 0; p < 6; ++p) { 5637 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 5638 } 5639 #endif 5640 /* F hex */ 5641 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 5642 orntNew[0] = -4; 5643 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 5644 orntNew[1] = ornt[1]; 5645 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 5646 orntNew[2] = ornt[2]; 5647 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5648 orntNew[3] = -1; 5649 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 5650 orntNew[4] = ornt[4]; 5651 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 5652 orntNew[5] = 1; 5653 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 5654 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 5655 #if 1 5656 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); 5657 for (p = 0; p < 6; ++p) { 5658 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); 5659 } 5660 #endif 5661 /* G hex */ 5662 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 5663 orntNew[0] = -4; 5664 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 5665 orntNew[1] = ornt[1]; 5666 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5667 orntNew[2] = 0; 5668 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 5669 orntNew[3] = ornt[3]; 5670 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 5671 orntNew[4] = ornt[4]; 5672 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5673 orntNew[5] = -3; 5674 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 5675 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 5676 #if 1 5677 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); 5678 for (p = 0; p < 6; ++p) { 5679 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); 5680 } 5681 #endif 5682 /* H hex */ 5683 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5684 orntNew[0] = -4; 5685 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 5686 orntNew[1] = ornt[1]; 5687 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5688 orntNew[2] = -1; 5689 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 5690 orntNew[3] = ornt[3]; 5691 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5692 orntNew[4] = 3; 5693 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 5694 orntNew[5] = ornt[5]; 5695 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 5696 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 5697 #if 1 5698 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); 5699 for (p = 0; p < 6; ++p) { 5700 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); 5701 } 5702 #endif 5703 } 5704 /* Hybrid cells have 6 faces: Front, Back, Sides */ 5705 /* 5706 3---------2---------2 5707 | | | 5708 | D 2 C | 5709 | | | 5710 3----3----0----1----1 5711 | | | 5712 | A 0 B | 5713 | | | 5714 0---------0---------1 5715 */ 5716 for (c = cMax; c < cEnd; ++c) { 5717 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 5718 const PetscInt *cone, *ornt, *fornt; 5719 PetscInt coneNew[6], orntNew[6], o, of, i; 5720 5721 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5722 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5723 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 5724 o = ornt[0] < 0 ? -1 : 1; 5725 for (r = 0; r < 4; ++r) { 5726 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 5727 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 5728 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 5729 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]); 5730 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 5731 orntNew[0] = ornt[0]; 5732 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 5733 orntNew[1] = ornt[0]; 5734 of = fornt[edgeA] < 0 ? -1 : 1; 5735 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 5736 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 5737 orntNew[i] = ornt[edgeA]; 5738 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 5739 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 5740 orntNew[i] = 0; 5741 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 5742 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 5743 orntNew[i] = -2; 5744 of = fornt[edgeB] < 0 ? -1 : 1; 5745 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 5746 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 5747 orntNew[i] = ornt[edgeB]; 5748 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 5749 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 5750 #if 1 5751 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); 5752 for (p = 0; p < 2; ++p) { 5753 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); 5754 } 5755 for (p = 2; p < 6; ++p) { 5756 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); 5757 } 5758 #endif 5759 } 5760 } 5761 /* Interior split faces have 4 edges and the same cells as the parent */ 5762 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5763 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5764 for (f = fStart; f < fMax; ++f) { 5765 for (r = 0; r < 4; ++r) { 5766 /* TODO: This can come from GetFaces_Internal() */ 5767 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}; 5768 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 5769 const PetscInt *cone, *ornt, *support; 5770 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 5771 5772 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5773 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5774 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 5775 orntNew[(r+3)%4] = ornt[(r+3)%4]; 5776 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 5777 orntNew[(r+0)%4] = ornt[r]; 5778 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5779 orntNew[(r+1)%4] = 0; 5780 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 5781 orntNew[(r+2)%4] = -2; 5782 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5783 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5784 #if 1 5785 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5786 for (p = 0; p < 4; ++p) { 5787 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); 5788 } 5789 #endif 5790 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5791 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5792 for (s = 0; s < supportSize; ++s) { 5793 PetscInt subf; 5794 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5795 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5796 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5797 for (c = 0; c < coneSize; ++c) { 5798 if (cone[c] == f) break; 5799 } 5800 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 5801 if (support[s] < cMax) { 5802 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 5803 } else { 5804 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 5805 } 5806 } 5807 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5808 #if 1 5809 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5810 for (p = 0; p < supportSize; ++p) { 5811 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); 5812 } 5813 #endif 5814 } 5815 } 5816 /* Interior cell faces have 4 edges and 2 cells */ 5817 for (c = cStart; c < cMax; ++c) { 5818 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}; 5819 const PetscInt *cone, *ornt; 5820 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 5821 5822 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5823 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5824 /* A-D face */ 5825 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 5826 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 5827 orntNew[0] = 0; 5828 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5829 orntNew[1] = 0; 5830 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5831 orntNew[2] = -2; 5832 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 5833 orntNew[3] = -2; 5834 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5835 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5836 #if 1 5837 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5838 for (p = 0; p < 4; ++p) { 5839 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); 5840 } 5841 #endif 5842 /* C-D face */ 5843 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 5844 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 5845 orntNew[0] = 0; 5846 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5847 orntNew[1] = 0; 5848 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5849 orntNew[2] = -2; 5850 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 5851 orntNew[3] = -2; 5852 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5853 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5854 #if 1 5855 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5856 for (p = 0; p < 4; ++p) { 5857 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); 5858 } 5859 #endif 5860 /* B-C face */ 5861 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 5862 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 5863 orntNew[0] = -2; 5864 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 5865 orntNew[1] = 0; 5866 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5867 orntNew[2] = 0; 5868 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5869 orntNew[3] = -2; 5870 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5871 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5872 #if 1 5873 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5874 for (p = 0; p < 4; ++p) { 5875 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); 5876 } 5877 #endif 5878 /* A-B face */ 5879 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 5880 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 5881 orntNew[0] = -2; 5882 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 5883 orntNew[1] = 0; 5884 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5885 orntNew[2] = 0; 5886 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5887 orntNew[3] = -2; 5888 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5889 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5890 #if 1 5891 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5892 for (p = 0; p < 4; ++p) { 5893 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); 5894 } 5895 #endif 5896 /* E-F face */ 5897 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 5898 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5899 orntNew[0] = -2; 5900 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 5901 orntNew[1] = -2; 5902 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 5903 orntNew[2] = 0; 5904 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5905 orntNew[3] = 0; 5906 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5907 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5908 #if 1 5909 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5910 for (p = 0; p < 4; ++p) { 5911 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); 5912 } 5913 #endif 5914 /* F-G face */ 5915 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 5916 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5917 orntNew[0] = -2; 5918 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 5919 orntNew[1] = -2; 5920 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 5921 orntNew[2] = 0; 5922 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5923 orntNew[3] = 0; 5924 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5925 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5926 #if 1 5927 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5928 for (p = 0; p < 4; ++p) { 5929 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); 5930 } 5931 #endif 5932 /* G-H face */ 5933 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 5934 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 5935 orntNew[0] = -2; 5936 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 5937 orntNew[1] = 0; 5938 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5939 orntNew[2] = 0; 5940 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5941 orntNew[3] = -2; 5942 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5943 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5944 #if 1 5945 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5946 for (p = 0; p < 4; ++p) { 5947 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); 5948 } 5949 #endif 5950 /* E-H face */ 5951 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 5952 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5953 orntNew[0] = -2; 5954 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 5955 orntNew[1] = -2; 5956 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 5957 orntNew[2] = 0; 5958 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5959 orntNew[3] = 0; 5960 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5961 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5962 #if 1 5963 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5964 for (p = 0; p < 4; ++p) { 5965 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); 5966 } 5967 #endif 5968 /* A-E face */ 5969 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 5970 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 5971 orntNew[0] = 0; 5972 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5973 orntNew[1] = 0; 5974 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5975 orntNew[2] = -2; 5976 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 5977 orntNew[3] = -2; 5978 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5979 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5980 #if 1 5981 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5982 for (p = 0; p < 4; ++p) { 5983 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); 5984 } 5985 #endif 5986 /* D-F face */ 5987 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 5988 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 5989 orntNew[0] = -2; 5990 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 5991 orntNew[1] = 0; 5992 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5993 orntNew[2] = 0; 5994 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5995 orntNew[3] = -2; 5996 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5997 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5998 #if 1 5999 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 6000 for (p = 0; p < 4; ++p) { 6001 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); 6002 } 6003 #endif 6004 /* C-G face */ 6005 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 6006 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 6007 orntNew[0] = -2; 6008 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 6009 orntNew[1] = -2; 6010 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 6011 orntNew[2] = 0; 6012 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 6013 orntNew[3] = 0; 6014 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6015 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6016 #if 1 6017 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 6018 for (p = 0; p < 4; ++p) { 6019 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); 6020 } 6021 #endif 6022 /* B-H face */ 6023 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 6024 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 6025 orntNew[0] = 0; 6026 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 6027 orntNew[1] = -2; 6028 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 6029 orntNew[2] = -2; 6030 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 6031 orntNew[3] = 0; 6032 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6033 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6034 #if 1 6035 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 6036 for (p = 0; p < 4; ++p) { 6037 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); 6038 } 6039 #endif 6040 for (r = 0; r < 12; ++r) { 6041 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 6042 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 6043 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 6044 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6045 #if 1 6046 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 6047 for (p = 0; p < 2; ++p) { 6048 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); 6049 } 6050 #endif 6051 } 6052 } 6053 /* Hybrid split faces have 4 edges and same cells */ 6054 for (f = fMax; f < fEnd; ++f) { 6055 const PetscInt *cone, *ornt, *support; 6056 PetscInt coneNew[4], orntNew[4]; 6057 PetscInt supportNew[2], size, s, c; 6058 6059 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6060 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6061 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6062 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6063 for (r = 0; r < 2; ++r) { 6064 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 6065 6066 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 6067 orntNew[0] = ornt[0]; 6068 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 6069 orntNew[1] = ornt[1]; 6070 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 6071 orntNew[2+r] = 0; 6072 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 6073 orntNew[3-r] = 0; 6074 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6075 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6076 #if 1 6077 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 6078 for (p = 0; p < 2; ++p) { 6079 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); 6080 } 6081 for (p = 2; p < 4; ++p) { 6082 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); 6083 } 6084 #endif 6085 for (s = 0; s < size; ++s) { 6086 const PetscInt *coneCell, *orntCell, *fornt; 6087 PetscInt o, of; 6088 6089 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6090 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6091 o = orntCell[0] < 0 ? -1 : 1; 6092 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 6093 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 6094 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 6095 of = fornt[c-2] < 0 ? -1 : 1; 6096 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 6097 } 6098 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6099 #if 1 6100 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 6101 for (p = 0; p < size; ++p) { 6102 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); 6103 } 6104 #endif 6105 } 6106 } 6107 /* Hybrid cell faces have 4 edges and 2 cells */ 6108 for (c = cMax; c < cEnd; ++c) { 6109 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 6110 const PetscInt *cone, *ornt; 6111 PetscInt coneNew[4], orntNew[4]; 6112 PetscInt supportNew[2]; 6113 6114 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6115 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6116 for (r = 0; r < 4; ++r) { 6117 #if 0 6118 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 6119 orntNew[0] = 0; 6120 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 6121 orntNew[1] = 0; 6122 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 6123 orntNew[2] = 0; 6124 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6125 orntNew[3] = 0; 6126 #else 6127 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 6128 orntNew[0] = 0; 6129 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 6130 orntNew[1] = 0; 6131 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 6132 orntNew[2] = 0; 6133 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6134 orntNew[3] = 0; 6135 #endif 6136 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 6137 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 6138 #if 1 6139 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); 6140 for (p = 0; p < 2; ++p) { 6141 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); 6142 } 6143 for (p = 2; p < 4; ++p) { 6144 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); 6145 } 6146 #endif 6147 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 6148 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 6149 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 6150 #if 1 6151 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); 6152 for (p = 0; p < 2; ++p) { 6153 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); 6154 } 6155 #endif 6156 } 6157 } 6158 /* Interior split edges have 2 vertices and the same faces as the parent */ 6159 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6160 for (e = eStart; e < eMax; ++e) { 6161 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6162 6163 for (r = 0; r < 2; ++r) { 6164 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6165 const PetscInt *cone, *ornt, *support; 6166 PetscInt coneNew[2], coneSize, c, supportSize, s; 6167 6168 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6169 coneNew[0] = vStartNew + (cone[0] - vStart); 6170 coneNew[1] = vStartNew + (cone[1] - vStart); 6171 coneNew[(r+1)%2] = newv; 6172 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6173 #if 1 6174 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6175 for (p = 0; p < 2; ++p) { 6176 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); 6177 } 6178 #endif 6179 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6180 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6181 for (s = 0; s < supportSize; ++s) { 6182 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6183 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6184 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6185 for (c = 0; c < coneSize; ++c) { 6186 if (cone[c] == e) break; 6187 } 6188 if (support[s] < fMax) { 6189 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 6190 } else { 6191 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6192 } 6193 } 6194 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6195 #if 1 6196 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6197 for (p = 0; p < supportSize; ++p) { 6198 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); 6199 } 6200 #endif 6201 } 6202 } 6203 /* Interior face edges have 2 vertices and 2+cells faces */ 6204 for (f = fStart; f < fMax; ++f) { 6205 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}; 6206 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6207 const PetscInt *cone, *coneCell, *orntCell, *support; 6208 PetscInt coneNew[2], coneSize, c, supportSize, s; 6209 6210 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6211 for (r = 0; r < 4; ++r) { 6212 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 6213 6214 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6215 coneNew[1] = newv; 6216 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6217 #if 1 6218 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6219 for (p = 0; p < 2; ++p) { 6220 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); 6221 } 6222 #endif 6223 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6224 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6225 supportRef[0] = fStartNew + (f - fStart)*4 + r; 6226 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 6227 for (s = 0; s < supportSize; ++s) { 6228 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6229 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6230 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6231 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 6232 if (support[s] < cMax) { 6233 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 6234 } else { 6235 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 6236 } 6237 } 6238 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6239 #if 1 6240 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6241 for (p = 0; p < 2+supportSize; ++p) { 6242 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); 6243 } 6244 #endif 6245 } 6246 } 6247 /* Interior cell edges have 2 vertices and 4 faces */ 6248 for (c = cStart; c < cMax; ++c) { 6249 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}; 6250 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 6251 const PetscInt *cone; 6252 PetscInt coneNew[2], supportNew[4]; 6253 6254 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6255 for (r = 0; r < 6; ++r) { 6256 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 6257 6258 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6259 coneNew[1] = newv; 6260 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6261 #if 1 6262 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6263 for (p = 0; p < 2; ++p) { 6264 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); 6265 } 6266 #endif 6267 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 6268 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6269 #if 1 6270 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6271 for (p = 0; p < 4; ++p) { 6272 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); 6273 } 6274 #endif 6275 } 6276 } 6277 /* Hybrid edges have two vertices and the same faces */ 6278 for (e = eMax; e < eEnd; ++e) { 6279 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 6280 const PetscInt *cone, *support, *fcone; 6281 PetscInt coneNew[2], size, fsize, s; 6282 6283 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6284 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6285 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6286 coneNew[0] = vStartNew + (cone[0] - vStart); 6287 coneNew[1] = vStartNew + (cone[1] - vStart); 6288 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6289 #if 1 6290 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6291 for (p = 0; p < 2; ++p) { 6292 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); 6293 } 6294 #endif 6295 for (s = 0; s < size; ++s) { 6296 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6297 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6298 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6299 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 6300 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 6301 } 6302 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6303 #if 1 6304 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6305 for (p = 0; p < size; ++p) { 6306 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); 6307 } 6308 #endif 6309 } 6310 /* Hybrid face edges have 2 vertices and 2+cells faces */ 6311 for (f = fMax; f < fEnd; ++f) { 6312 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 6313 const PetscInt *cone, *support, *ccone, *cornt; 6314 PetscInt coneNew[2], size, csize, s; 6315 6316 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6317 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6318 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6319 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6320 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6321 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6322 #if 1 6323 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6324 for (p = 0; p < 2; ++p) { 6325 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); 6326 } 6327 #endif 6328 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 6329 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 6330 for (s = 0; s < size; ++s) { 6331 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 6332 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 6333 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 6334 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 6335 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]); 6336 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 6337 } 6338 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6339 #if 1 6340 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6341 for (p = 0; p < 2+size; ++p) { 6342 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); 6343 } 6344 #endif 6345 } 6346 /* Hybrid cell edges have 2 vertices and 4 faces */ 6347 for (c = cMax; c < cEnd; ++c) { 6348 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6349 const PetscInt *cone, *support; 6350 PetscInt coneNew[2], size; 6351 6352 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6353 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 6354 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 6355 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6356 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6357 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6358 #if 1 6359 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6360 for (p = 0; p < 2; ++p) { 6361 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); 6362 } 6363 #endif 6364 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 6365 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 6366 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 6367 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 6368 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6369 #if 1 6370 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6371 for (p = 0; p < 4; ++p) { 6372 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); 6373 } 6374 #endif 6375 } 6376 /* Interior vertices have identical supports */ 6377 for (v = vStart; v < vEnd; ++v) { 6378 const PetscInt newp = vStartNew + (v - vStart); 6379 const PetscInt *support, *cone; 6380 PetscInt size, s; 6381 6382 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6383 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6384 for (s = 0; s < size; ++s) { 6385 PetscInt r = 0; 6386 6387 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6388 if (cone[1] == v) r = 1; 6389 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 6390 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 6391 } 6392 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6393 #if 1 6394 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6395 for (p = 0; p < size; ++p) { 6396 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); 6397 } 6398 #endif 6399 } 6400 /* Interior edge vertices have 2 + faces supports */ 6401 for (e = eStart; e < eMax; ++e) { 6402 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6403 const PetscInt *cone, *support; 6404 PetscInt size, s; 6405 6406 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6407 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6408 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6409 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6410 for (s = 0; s < size; ++s) { 6411 PetscInt r; 6412 6413 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6414 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 6415 if (support[s] < fMax) { 6416 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 6417 } else { 6418 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 6419 } 6420 } 6421 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6422 #if 1 6423 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6424 for (p = 0; p < 2+size; ++p) { 6425 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); 6426 } 6427 #endif 6428 } 6429 /* Interior face vertices have 4 + cells supports */ 6430 for (f = fStart; f < fMax; ++f) { 6431 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6432 const PetscInt *cone, *support; 6433 PetscInt size, s; 6434 6435 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6436 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6437 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 6438 for (s = 0; s < size; ++s) { 6439 PetscInt r; 6440 6441 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6442 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 6443 if (support[s] < cMax) { 6444 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 6445 } else { 6446 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 6447 } 6448 } 6449 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6450 #if 1 6451 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6452 for (p = 0; p < 4+size; ++p) { 6453 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); 6454 } 6455 #endif 6456 } 6457 /* Cell vertices have 6 supports */ 6458 for (c = cStart; c < cMax; ++c) { 6459 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 6460 PetscInt supportNew[6]; 6461 6462 for (r = 0; r < 6; ++r) { 6463 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 6464 } 6465 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6466 } 6467 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6468 break; 6469 default: 6470 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6471 } 6472 PetscFunctionReturn(0); 6473 } 6474 6475 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6476 { 6477 PetscSection coordSection, coordSectionNew; 6478 Vec coordinates, coordinatesNew; 6479 PetscScalar *coords, *coordsNew; 6480 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 6481 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 6482 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 6483 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 6484 VecType vtype; 6485 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 6486 const PetscReal *maxCell, *L; 6487 const DMBoundaryType *bd; 6488 PetscErrorCode ierr; 6489 6490 PetscFunctionBegin; 6491 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6492 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6493 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6494 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6495 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6496 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6497 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 6498 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 6499 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 6500 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 6501 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 6502 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 6503 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 6504 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 6505 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 6506 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 6507 /* Determine if we need to localize coordinates when generating them */ 6508 if (isperiodic && !maxCell) { 6509 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 6510 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 6511 } 6512 if (localize) { 6513 PetscInt p, r, newp, *pi; 6514 6515 /* New coordinates will be already localized on the cell */ 6516 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 6517 6518 /* We need the parentId to properly localize coordinates */ 6519 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 6520 switch (refiner) { 6521 case REFINER_NOOP: 6522 break; 6523 case REFINER_SIMPLEX_1D: 6524 for (p = cStart; p < cEnd; ++p) { 6525 for (r = 0; r < 2; ++r) { 6526 newp = (p - cStart)*2 + r; 6527 pi[newp] = p; 6528 } 6529 } 6530 break; 6531 case REFINER_SIMPLEX_2D: 6532 for (p = cStart; p < cEnd; ++p) { 6533 for (r = 0; r < 4; ++r) { 6534 newp = (p - cStart)*4 + r; 6535 pi[newp] = p; 6536 } 6537 } 6538 break; 6539 case REFINER_HEX_2D: 6540 for (p = cStart; p < cEnd; ++p) { 6541 for (r = 0; r < 4; ++r) { 6542 newp = (p - cStart)*4 + r; 6543 pi[newp] = p; 6544 } 6545 } 6546 break; 6547 case REFINER_SIMPLEX_TO_HEX_2D: 6548 for (p = cStart; p < cEnd; ++p) { 6549 for (r = 0; r < 3; ++r) { 6550 newp = (p - cStart)*3 + r; 6551 pi[newp] = p; 6552 } 6553 } 6554 break; 6555 case REFINER_HYBRID_SIMPLEX_2D: 6556 for (p = cStart; p < cMax; ++p) { 6557 for (r = 0; r < 4; ++r) { 6558 newp = (p - cStart)*4 + r; 6559 pi[newp] = p; 6560 } 6561 } 6562 for (p = cMax; p < cEnd; ++p) { 6563 for (r = 0; r < 2; ++r) { 6564 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 6565 pi[newp] = p; 6566 } 6567 } 6568 break; 6569 case REFINER_HYBRID_HEX_2D: 6570 for (p = cStart; p < cMax; ++p) { 6571 for (r = 0; r < 4; ++r) { 6572 newp = (p - cStart)*4 + r; 6573 pi[newp] = p; 6574 } 6575 } 6576 for (p = cMax; p < cEnd; ++p) { 6577 for (r = 0; r < 2; ++r) { 6578 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 6579 pi[newp] = p; 6580 } 6581 } 6582 break; 6583 case REFINER_SIMPLEX_3D: 6584 for (p = cStart; p < cEnd; ++p) { 6585 for (r = 0; r < 8; ++r) { 6586 newp = (p - cStart)*8 + r; 6587 pi[newp] = p; 6588 } 6589 } 6590 break; 6591 case REFINER_HYBRID_SIMPLEX_3D: 6592 for (p = cStart; p < cMax; ++p) { 6593 for (r = 0; r < 8; ++r) { 6594 newp = (p - cStart)*8 + r; 6595 pi[newp] = p; 6596 } 6597 } 6598 for (p = cMax; p < cEnd; ++p) { 6599 for (r = 0; r < 4; ++r) { 6600 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 6601 pi[newp] = p; 6602 } 6603 } 6604 break; 6605 case REFINER_SIMPLEX_TO_HEX_3D: 6606 for (p = cStart; p < cEnd; ++p) { 6607 for (r = 0; r < 4; ++r) { 6608 newp = (p - cStart)*4 + r; 6609 pi[newp] = p; 6610 } 6611 } 6612 break; 6613 case REFINER_HEX_3D: 6614 for (p = cStart; p < cEnd; ++p) { 6615 for (r = 0; r < 8; ++r) { 6616 newp = (p - cStart)*8 + r; 6617 pi[newp] = p; 6618 } 6619 } 6620 break; 6621 case REFINER_HYBRID_HEX_3D: 6622 for (p = cStart; p < cMax; ++p) { 6623 for (r = 0; r < 8; ++r) { 6624 newp = (p - cStart)*8 + r; 6625 pi[newp] = p; 6626 } 6627 } 6628 for (p = cMax; p < cEnd; ++p) { 6629 for (r = 0; r < 4; ++r) { 6630 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 6631 pi[newp] = p; 6632 } 6633 } 6634 break; 6635 default: 6636 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6637 } 6638 parentId = pi; 6639 } else { 6640 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 6641 } 6642 if (cMax < 0) cMax = cEnd; 6643 if (fMax < 0) fMax = fEnd; 6644 if (eMax < 0) eMax = eEnd; 6645 6646 /* All vertices have the spaceDim coordinates */ 6647 if (localize) { 6648 PetscInt c; 6649 6650 for (c = cStartNew; c < cEndNew; ++c) { 6651 PetscInt *cone = NULL; 6652 PetscInt closureSize, coneSize = 0, p, pdof; 6653 6654 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 6655 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 6656 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6657 for (p = 0; p < closureSize*2; p += 2) { 6658 const PetscInt point = cone[p]; 6659 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 6660 } 6661 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6662 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 6663 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 6664 } 6665 } 6666 } 6667 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 6668 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 6669 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 6670 } 6671 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 6672 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 6673 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 6674 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 6675 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 6676 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 6677 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 6678 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 6679 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 6680 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 6681 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 6682 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 6683 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 6684 6685 switch (refiner) { 6686 case REFINER_NOOP: break; 6687 case REFINER_SIMPLEX_TO_HEX_3D: 6688 case REFINER_HEX_3D: 6689 case REFINER_HYBRID_HEX_3D: 6690 /* Face vertices have the average of corner coordinates */ 6691 for (f = fStart; f < fMax; ++f) { 6692 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6693 PetscInt *cone = NULL; 6694 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 6695 6696 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6697 for (p = 0; p < closureSize*2; p += 2) { 6698 const PetscInt point = cone[p]; 6699 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6700 } 6701 if (localize) { 6702 const PetscInt *support = NULL; 6703 PetscInt *rStar = NULL; 6704 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 6705 PetscBool cellfound = PETSC_FALSE; 6706 6707 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6708 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 6709 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 6710 /* Compute average of coordinates for each cell sharing the face */ 6711 for (s = 0; s < supportSize; ++s) { 6712 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 6713 PetscInt *cellCone = NULL; 6714 PetscInt cellClosureSize, cellConeSize = 0, cdof; 6715 const PetscInt cell = support[s]; 6716 PetscBool copyoff = PETSC_FALSE; 6717 6718 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6719 for (p = 0; p < cellClosureSize*2; p += 2) { 6720 const PetscInt point = cellCone[p]; 6721 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 6722 } 6723 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 6724 if (!cdof) { /* the parent cell does not have localized coordinates */ 6725 cellfound = PETSC_TRUE; 6726 for (v = 0; v < coneSize; ++v) { 6727 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6728 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 6729 } 6730 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 6731 } else { 6732 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 6733 for (p = 0; p < coneSize; ++p) { 6734 const PetscInt tv = cone[p]; 6735 PetscInt cv, voff; 6736 PetscBool locv = PETSC_TRUE; 6737 6738 for (cv = 0; cv < cellConeSize; ++cv) { 6739 if (cellCone[cv] == tv) { 6740 ccoff[p] = spaceDim*cv + coff; 6741 break; 6742 } 6743 } 6744 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D\n",tv); 6745 6746 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 6747 for (d = 0; d < spaceDim; ++d) { 6748 coordsNewAux[d] += coords[ccoff[p]+d]; 6749 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 6750 } 6751 if (locv && !cellfound) { 6752 cellfound = PETSC_TRUE; 6753 copyoff = PETSC_TRUE; 6754 } 6755 } 6756 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 6757 6758 /* Found a valid face for the "vertex" part of the Section (physical space) 6759 i.e., a face that has at least one corner in the physical space */ 6760 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 6761 } 6762 6763 /* Localize new coordinates on each refined cell */ 6764 for (v = 0; v < rStarSize*2; v += 2) { 6765 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 6766 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 6767 const PetscInt rcell = rStar[v]; 6768 6769 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 6770 if (!rcdof) continue; 6771 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 6772 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6773 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 6774 if (rcone[p] == newv) { 6775 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 6776 break; 6777 } 6778 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 6779 } 6780 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6781 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6782 } 6783 } 6784 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6785 } 6786 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6787 if (!cellfound) { 6788 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 6789 needcoords = PETSC_TRUE; 6790 coneSize = 0; 6791 } 6792 } else { 6793 for (v = 0; v < coneSize; ++v) { 6794 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6795 } 6796 } 6797 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6798 if (coneSize) { 6799 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6800 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6801 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6802 } else { 6803 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 6804 } 6805 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6806 } 6807 case REFINER_SIMPLEX_TO_HEX_2D: 6808 case REFINER_HEX_2D: 6809 case REFINER_HYBRID_HEX_2D: 6810 case REFINER_SIMPLEX_1D: 6811 /* Cell vertices have the average of corner coordinates */ 6812 for (c = cStart; c < cMax; ++c) { 6813 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 6814 PetscInt *cone = NULL; 6815 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 6816 6817 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6818 for (p = 0; p < closureSize*2; p += 2) { 6819 const PetscInt point = cone[p]; 6820 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6821 } 6822 if (localize) { 6823 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 6824 } 6825 if (cdof) { 6826 PetscInt coff; 6827 6828 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 6829 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 6830 } else { 6831 for (v = 0; v < coneSize; ++v) { 6832 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6833 } 6834 } 6835 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6836 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6837 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6838 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6839 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6840 6841 /* Localize new coordinates on each refined cell */ 6842 if (cdof) { 6843 PetscInt *rStar = NULL, rStarSize; 6844 6845 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6846 for (v = 0; v < rStarSize*2; v += 2) { 6847 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 6848 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 6849 6850 rc = rStar[v]; 6851 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 6852 if (!rcdof) continue; 6853 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 6854 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6855 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 6856 if (cone[p] == newv) { 6857 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 6858 break; 6859 } 6860 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 6861 } 6862 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6863 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6864 } 6865 } 6866 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6867 } 6868 } 6869 case REFINER_SIMPLEX_2D: 6870 case REFINER_HYBRID_SIMPLEX_2D: 6871 case REFINER_SIMPLEX_3D: 6872 case REFINER_HYBRID_SIMPLEX_3D: 6873 /* Edge vertices have the average of endpoint coordinates */ 6874 for (e = eStart; e < eMax; ++e) { 6875 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6876 const PetscInt *cone; 6877 PetscInt coneSize, offA, offB, offnew, d; 6878 6879 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 6880 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 6881 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6882 if (localize) { 6883 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 6884 PetscInt *eStar = NULL, eStarSize; 6885 PetscInt *rStar = NULL, rStarSize; 6886 PetscBool cellfound = PETSC_FALSE; 6887 6888 offA = offB = -1; 6889 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 6890 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 6891 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 6892 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6893 for (v = 0; v < eStarSize*2; v += 2) { 6894 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 6895 PetscScalar coordsNewAux[3]; 6896 PetscInt *cellCone = NULL; 6897 PetscInt cellClosureSize, s, cv, cdof; 6898 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 6899 const PetscInt cell = eStar[v]; 6900 6901 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 6902 if (!cdof) { 6903 /* Found a valid edge for the "vertex" part of the Section */ 6904 offA = voffA; 6905 offB = voffB; 6906 cellfound = PETSC_TRUE; 6907 } else { 6908 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 6909 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6910 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 6911 const PetscInt point = cellCone[s]; 6912 if ((point >= vStart) && (point < vEnd)) { 6913 if (point == cone[0]) toffA = spaceDim*cv + coff; 6914 else if (point == cone[1]) toffB = spaceDim*cv + coff; 6915 cv++; 6916 } 6917 } 6918 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6919 for (d = 0; d < spaceDim; ++d) { 6920 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 6921 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 6922 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 6923 } 6924 /* Found a valid edge for the "vertex" part of the Section */ 6925 if (!cellfound && (locvA || locvB)) { 6926 cellfound = PETSC_TRUE; 6927 offA = toffA; 6928 offB = toffB; 6929 } 6930 } 6931 6932 /* Localize new coordinates on each refined cell */ 6933 for (s = 0; s < rStarSize*2; s += 2) { 6934 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 6935 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 6936 const PetscInt rcell = rStar[s]; 6937 6938 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 6939 if (!rcdof) continue; 6940 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 6941 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6942 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 6943 if (rcone[p] == newv) { 6944 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 6945 break; 6946 } 6947 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 6948 } 6949 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6950 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6951 } 6952 } 6953 } 6954 } 6955 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 6956 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6957 if (!cellfound) { 6958 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 6959 needcoords = PETSC_TRUE; 6960 } 6961 } else { 6962 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 6963 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 6964 } 6965 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6966 if (offA != -1 && offB != -1) { 6967 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 6968 for (d = 0; d < spaceDim; ++d) { 6969 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 6970 } 6971 } else { 6972 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 6973 } 6974 } 6975 /* Old vertices have the same coordinates */ 6976 for (v = vStart; v < vEnd; ++v) { 6977 const PetscInt newv = vStartNew + (v - vStart); 6978 PetscInt off, offnew, d; 6979 6980 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 6981 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6982 for (d = 0; d < spaceDim; ++d) { 6983 coordsNew[offnew+d] = coords[off+d]; 6984 } 6985 6986 /* Localize new coordinates on each refined cell */ 6987 if (localize) { 6988 PetscInt p; 6989 PetscInt *rStar = NULL, rStarSize; 6990 6991 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6992 for (p = 0; p < rStarSize*2; p += 2) { 6993 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 6994 PetscScalar ocoords[3]; 6995 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 6996 6997 c = rStar[p]; 6998 oc = parentId[c-cStartNew]; 6999 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 7000 if (!cdof) continue; 7001 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 7002 if (!cdof) continue; 7003 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 7004 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7005 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 7006 if (cone[s] == v) { 7007 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 7008 break; 7009 } 7010 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 7011 } 7012 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D\n",v); 7013 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7014 7015 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 7016 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7017 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 7018 if (cone[s] == newv) { 7019 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 7020 break; 7021 } 7022 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 7023 } 7024 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 7025 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7026 } 7027 } 7028 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 7029 } 7030 } 7031 break; 7032 default: 7033 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7034 } 7035 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 7036 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 7037 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 7038 7039 /* Final reduction (if needed) if we are localizing */ 7040 if (localize) { 7041 PetscBool gred; 7042 7043 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 7044 if (gred) { 7045 DM cdm; 7046 Vec aux; 7047 PetscSF sf; 7048 const PetscScalar *lArray; 7049 PetscScalar *gArray; 7050 7051 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 7052 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 7053 ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr); 7054 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 7055 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 7056 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 7057 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 7058 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 7059 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 7060 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 7061 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 7062 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 7063 ierr = VecDestroy(&aux);CHKERRQ(ierr); 7064 } 7065 } 7066 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 7067 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 7068 ierr = PetscFree(parentId);CHKERRQ(ierr); 7069 PetscFunctionReturn(0); 7070 } 7071 7072 /*@ 7073 DMPlexCreateProcessSF - Create an SF which just has process connectivity 7074 7075 Collective on DM 7076 7077 Input Parameters: 7078 + dm - The DM 7079 - sfPoint - The PetscSF which encodes point connectivity 7080 7081 Output Parameters: 7082 + processRanks - A list of process neighbors, or NULL 7083 - sfProcess - An SF encoding the process connectivity, or NULL 7084 7085 Level: developer 7086 7087 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 7088 @*/ 7089 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 7090 { 7091 PetscInt numRoots, numLeaves, l; 7092 const PetscInt *localPoints; 7093 const PetscSFNode *remotePoints; 7094 PetscInt *localPointsNew; 7095 PetscSFNode *remotePointsNew; 7096 PetscInt *ranks, *ranksNew; 7097 PetscMPIInt size; 7098 PetscErrorCode ierr; 7099 7100 PetscFunctionBegin; 7101 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7102 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 7103 if (processRanks) {PetscValidPointer(processRanks, 3);} 7104 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 7105 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 7106 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 7107 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 7108 for (l = 0; l < numLeaves; ++l) { 7109 ranks[l] = remotePoints[l].rank; 7110 } 7111 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 7112 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 7113 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 7114 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 7115 for (l = 0; l < numLeaves; ++l) { 7116 ranksNew[l] = ranks[l]; 7117 localPointsNew[l] = l; 7118 remotePointsNew[l].index = 0; 7119 remotePointsNew[l].rank = ranksNew[l]; 7120 } 7121 ierr = PetscFree(ranks);CHKERRQ(ierr); 7122 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 7123 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 7124 if (sfProcess) { 7125 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 7126 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 7127 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 7128 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 7129 } 7130 PetscFunctionReturn(0); 7131 } 7132 7133 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 7134 { 7135 PetscSF sf, sfNew, sfProcess; 7136 IS processRanks; 7137 MPI_Datatype depthType; 7138 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 7139 const PetscInt *localPoints, *neighbors; 7140 const PetscSFNode *remotePoints; 7141 PetscInt *localPointsNew; 7142 PetscSFNode *remotePointsNew; 7143 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 7144 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 7145 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7146 PetscErrorCode ierr; 7147 7148 PetscFunctionBegin; 7149 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 7150 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 7151 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 7152 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth); 7153 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7154 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 7155 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7156 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7157 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7158 cMax = cMax < 0 ? cEnd : cMax; 7159 fMax = fMax < 0 ? fEnd : fMax; 7160 eMax = eMax < 0 ? eEnd : eMax; 7161 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7162 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 7163 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 7164 /* Calculate size of new SF */ 7165 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 7166 if (numRoots < 0) PetscFunctionReturn(0); 7167 for (l = 0; l < numLeaves; ++l) { 7168 const PetscInt p = localPoints[l]; 7169 7170 switch (refiner) { 7171 case REFINER_SIMPLEX_1D: 7172 if ((p >= vStart) && (p < vEnd)) { 7173 /* Interior vertices stay the same */ 7174 ++numLeavesNew; 7175 } else if ((p >= cStart && p < cMax)) { 7176 /* Interior cells add new cells and interior vertices */ 7177 numLeavesNew += 2 + 1; 7178 } 7179 break; 7180 case REFINER_SIMPLEX_2D: 7181 case REFINER_HYBRID_SIMPLEX_2D: 7182 if ((p >= vStart) && (p < vEnd)) { 7183 /* Interior vertices stay the same */ 7184 ++numLeavesNew; 7185 } else if ((p >= fStart) && (p < fMax)) { 7186 /* Interior faces add new faces and vertex */ 7187 numLeavesNew += 2 + 1; 7188 } else if ((p >= fMax) && (p < fEnd)) { 7189 /* Hybrid faces stay the same */ 7190 ++numLeavesNew; 7191 } else if ((p >= cStart) && (p < cMax)) { 7192 /* Interior cells add new cells and interior faces */ 7193 numLeavesNew += 4 + 3; 7194 } else if ((p >= cMax) && (p < cEnd)) { 7195 /* Hybrid cells add new cells and hybrid face */ 7196 numLeavesNew += 2 + 1; 7197 } 7198 break; 7199 case REFINER_SIMPLEX_TO_HEX_2D: 7200 if ((p >= vStart) && (p < vEnd)) { 7201 /* Interior vertices stay the same */ 7202 ++numLeavesNew; 7203 } else if ((p >= fStart) && (p < fEnd)) { 7204 /* Interior faces add new faces and vertex */ 7205 numLeavesNew += 2 + 1; 7206 } else if ((p >= cStart) && (p < cEnd)) { 7207 /* Interior cells add new cells, interior faces, and vertex */ 7208 numLeavesNew += 3 + 3 + 1; 7209 } 7210 break; 7211 case REFINER_HEX_2D: 7212 case REFINER_HYBRID_HEX_2D: 7213 if ((p >= vStart) && (p < vEnd)) { 7214 /* Interior vertices stay the same */ 7215 ++numLeavesNew; 7216 } else if ((p >= fStart) && (p < fMax)) { 7217 /* Interior faces add new faces and vertex */ 7218 numLeavesNew += 2 + 1; 7219 } else if ((p >= fMax) && (p < fEnd)) { 7220 /* Hybrid faces stay the same */ 7221 ++numLeavesNew; 7222 } else if ((p >= cStart) && (p < cMax)) { 7223 /* Interior cells add new cells, interior faces, and vertex */ 7224 numLeavesNew += 4 + 4 + 1; 7225 } else if ((p >= cMax) && (p < cEnd)) { 7226 /* Hybrid cells add new cells and hybrid face */ 7227 numLeavesNew += 2 + 1; 7228 } 7229 break; 7230 case REFINER_SIMPLEX_3D: 7231 case REFINER_HYBRID_SIMPLEX_3D: 7232 if ((p >= vStart) && (p < vEnd)) { 7233 /* Interior vertices stay the same */ 7234 ++numLeavesNew; 7235 } else if ((p >= eStart) && (p < eMax)) { 7236 /* Interior edges add new edges and vertex */ 7237 numLeavesNew += 2 + 1; 7238 } else if ((p >= eMax) && (p < eEnd)) { 7239 /* Hybrid edges stay the same */ 7240 ++numLeavesNew; 7241 } else if ((p >= fStart) && (p < fMax)) { 7242 /* Interior faces add new faces and edges */ 7243 numLeavesNew += 4 + 3; 7244 } else if ((p >= fMax) && (p < fEnd)) { 7245 /* Hybrid faces add new faces and edges */ 7246 numLeavesNew += 2 + 1; 7247 } else if ((p >= cStart) && (p < cMax)) { 7248 /* Interior cells add new cells, faces, and edges */ 7249 numLeavesNew += 8 + 8 + 1; 7250 } else if ((p >= cMax) && (p < cEnd)) { 7251 /* Hybrid cells add new cells and faces */ 7252 numLeavesNew += 4 + 3; 7253 } 7254 break; 7255 case REFINER_SIMPLEX_TO_HEX_3D: 7256 if ((p >= vStart) && (p < vEnd)) { 7257 /* Interior vertices stay the same */ 7258 ++numLeavesNew; 7259 } else if ((p >= eStart) && (p < eEnd)) { 7260 /* Interior edges add new edges and vertex */ 7261 numLeavesNew += 2 + 1; 7262 } else if ((p >= fStart) && (p < fEnd)) { 7263 /* Interior faces add new faces, edges and a vertex */ 7264 numLeavesNew += 3 + 3 + 1; 7265 } else if ((p >= cStart) && (p < cEnd)) { 7266 /* Interior cells add new cells, faces, edges and a vertex */ 7267 numLeavesNew += 4 + 6 + 4 + 1; 7268 } 7269 break; 7270 case REFINER_HEX_3D: 7271 case REFINER_HYBRID_HEX_3D: 7272 if ((p >= vStart) && (p < vEnd)) { 7273 /* Old vertices stay the same */ 7274 ++numLeavesNew; 7275 } else if ((p >= eStart) && (p < eMax)) { 7276 /* Interior edges add new edges, and vertex */ 7277 numLeavesNew += 2 + 1; 7278 } else if ((p >= eMax) && (p < eEnd)) { 7279 /* Hybrid edges stay the same */ 7280 ++numLeavesNew; 7281 } else if ((p >= fStart) && (p < fMax)) { 7282 /* Interior faces add new faces, edges, and vertex */ 7283 numLeavesNew += 4 + 4 + 1; 7284 } else if ((p >= fMax) && (p < fEnd)) { 7285 /* Hybrid faces add new faces and edges */ 7286 numLeavesNew += 2 + 1; 7287 } else if ((p >= cStart) && (p < cMax)) { 7288 /* Interior cells add new cells, faces, edges, and vertex */ 7289 numLeavesNew += 8 + 12 + 6 + 1; 7290 } else if ((p >= cStart) && (p < cEnd)) { 7291 /* Hybrid cells add new cells, faces, and edges */ 7292 numLeavesNew += 4 + 4 + 1; 7293 } 7294 break; 7295 default: 7296 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7297 } 7298 } 7299 /* Communicate depthSizes for each remote rank */ 7300 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 7301 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 7302 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 7303 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 7304 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 7305 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 7306 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 7307 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 7308 for (n = 0; n < numNeighbors; ++n) { 7309 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 7310 } 7311 depthSizeOld[depth] = cMax; 7312 depthSizeOld[0] = vMax; 7313 depthSizeOld[depth-1] = fMax; 7314 depthSizeOld[1] = eMax; 7315 7316 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 7317 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 7318 7319 depthSizeOld[depth] = cEnd - cStart; 7320 depthSizeOld[0] = vEnd - vStart; 7321 depthSizeOld[depth-1] = fEnd - fStart; 7322 depthSizeOld[1] = eEnd - eStart; 7323 7324 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 7325 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 7326 for (n = 0; n < numNeighbors; ++n) { 7327 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 7328 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 7329 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]; 7330 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 7331 } 7332 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 7333 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 7334 /* Calculate new point SF */ 7335 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 7336 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 7337 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 7338 for (l = 0, m = 0; l < numLeaves; ++l) { 7339 PetscInt p = localPoints[l]; 7340 PetscInt rp = remotePoints[l].index, n; 7341 PetscMPIInt rrank = remotePoints[l].rank; 7342 7343 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 7344 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 7345 switch (refiner) { 7346 case REFINER_SIMPLEX_1D: 7347 if ((p >= vStart) && (p < vEnd)) { 7348 /* Old vertices stay the same */ 7349 localPointsNew[m] = vStartNew + (p - vStart); 7350 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7351 remotePointsNew[m].rank = rrank; 7352 ++m; 7353 } else if ((p >= cStart) && (p < cMax)) { 7354 /* Old interior cells add new cells and vertex */ 7355 for (r = 0; r < 2; ++r, ++m) { 7356 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 7357 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 7358 remotePointsNew[m].rank = rrank; 7359 } 7360 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 7361 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 7362 remotePointsNew[m].rank = rrank; 7363 ++m; 7364 } 7365 break; 7366 case REFINER_SIMPLEX_2D: 7367 case REFINER_HYBRID_SIMPLEX_2D: 7368 if ((p >= vStart) && (p < vEnd)) { 7369 /* Old vertices stay the same */ 7370 localPointsNew[m] = vStartNew + (p - vStart); 7371 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7372 remotePointsNew[m].rank = rrank; 7373 ++m; 7374 } else if ((p >= fStart) && (p < fMax)) { 7375 /* Old interior faces add new faces and vertex */ 7376 for (r = 0; r < 2; ++r, ++m) { 7377 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7378 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7379 remotePointsNew[m].rank = rrank; 7380 } 7381 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7382 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7383 remotePointsNew[m].rank = rrank; 7384 ++m; 7385 } else if ((p >= fMax) && (p < fEnd)) { 7386 /* Old hybrid faces stay the same */ 7387 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 7388 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 7389 remotePointsNew[m].rank = rrank; 7390 ++m; 7391 } else if ((p >= cStart) && (p < cMax)) { 7392 /* Old interior cells add new cells and interior faces */ 7393 for (r = 0; r < 4; ++r, ++m) { 7394 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7395 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7396 remotePointsNew[m].rank = rrank; 7397 } 7398 for (r = 0; r < 3; ++r, ++m) { 7399 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 7400 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 7401 remotePointsNew[m].rank = rrank; 7402 } 7403 } else if ((p >= cMax) && (p < cEnd)) { 7404 /* Old hybrid cells add new cells and hybrid face */ 7405 for (r = 0; r < 2; ++r, ++m) { 7406 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7407 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7408 remotePointsNew[m].rank = rrank; 7409 } 7410 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 7411 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]); 7412 remotePointsNew[m].rank = rrank; 7413 ++m; 7414 } 7415 break; 7416 case REFINER_SIMPLEX_TO_HEX_2D: 7417 if ((p >= vStart) && (p < vEnd)) { 7418 /* Old vertices stay the same */ 7419 localPointsNew[m] = vStartNew + (p - vStart); 7420 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7421 remotePointsNew[m].rank = rrank; 7422 ++m; 7423 } else if ((p >= fStart) && (p < fEnd)) { 7424 /* Old interior faces add new faces and vertex */ 7425 for (r = 0; r < 2; ++r, ++m) { 7426 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7427 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7428 remotePointsNew[m].rank = rrank; 7429 } 7430 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7431 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7432 remotePointsNew[m].rank = rrank; 7433 ++m; 7434 } else if ((p >= cStart) && (p < cEnd)) { 7435 /* Old interior cells add new cells, interior faces, and a vertex */ 7436 for (r = 0; r < 3; ++r, ++m) { 7437 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 7438 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 7439 remotePointsNew[m].rank = rrank; 7440 } 7441 for (r = 0; r < 3; ++r, ++m) { 7442 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7443 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 7444 remotePointsNew[m].rank = rrank; 7445 } 7446 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7447 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 7448 remotePointsNew[m].rank = rrank; 7449 ++m; 7450 } 7451 break; 7452 case REFINER_HEX_2D: 7453 case REFINER_HYBRID_HEX_2D: 7454 if ((p >= vStart) && (p < vEnd)) { 7455 /* Old vertices stay the same */ 7456 localPointsNew[m] = vStartNew + (p - vStart); 7457 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7458 remotePointsNew[m].rank = rrank; 7459 ++m; 7460 } else if ((p >= fStart) && (p < fMax)) { 7461 /* Old interior faces add new faces and vertex */ 7462 for (r = 0; r < 2; ++r, ++m) { 7463 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7464 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7465 remotePointsNew[m].rank = rrank; 7466 } 7467 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7468 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7469 remotePointsNew[m].rank = rrank; 7470 ++m; 7471 } else if ((p >= fMax) && (p < fEnd)) { 7472 /* Old hybrid faces stay the same */ 7473 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 7474 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 7475 remotePointsNew[m].rank = rrank; 7476 ++m; 7477 } else if ((p >= cStart) && (p < cMax)) { 7478 /* Old interior cells add new cells, interior faces, and vertex */ 7479 for (r = 0; r < 4; ++r, ++m) { 7480 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7481 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7482 remotePointsNew[m].rank = rrank; 7483 } 7484 for (r = 0; r < 4; ++r, ++m) { 7485 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 7486 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 7487 remotePointsNew[m].rank = rrank; 7488 } 7489 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 7490 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 7491 remotePointsNew[m].rank = rrank; 7492 ++m; 7493 } else if ((p >= cStart) && (p < cMax)) { 7494 /* Old hybrid cells add new cells and hybrid face */ 7495 for (r = 0; r < 2; ++r, ++m) { 7496 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7497 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7498 remotePointsNew[m].rank = rrank; 7499 } 7500 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 7501 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]); 7502 remotePointsNew[m].rank = rrank; 7503 ++m; 7504 } 7505 break; 7506 case REFINER_SIMPLEX_3D: 7507 case REFINER_HYBRID_SIMPLEX_3D: 7508 if ((p >= vStart) && (p < vEnd)) { 7509 /* Interior vertices stay the same */ 7510 localPointsNew[m] = vStartNew + (p - vStart); 7511 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7512 remotePointsNew[m].rank = rrank; 7513 ++m; 7514 } else if ((p >= eStart) && (p < eMax)) { 7515 /* Interior edges add new edges and vertex */ 7516 for (r = 0; r < 2; ++r, ++m) { 7517 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7518 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7519 remotePointsNew[m].rank = rrank; 7520 } 7521 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7522 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7523 remotePointsNew[m].rank = rrank; 7524 ++m; 7525 } else if ((p >= eMax) && (p < eEnd)) { 7526 /* Hybrid edges stay the same */ 7527 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 7528 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]); 7529 remotePointsNew[m].rank = rrank; 7530 ++m; 7531 } else if ((p >= fStart) && (p < fMax)) { 7532 /* Interior faces add new faces and edges */ 7533 for (r = 0; r < 4; ++r, ++m) { 7534 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7535 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7536 remotePointsNew[m].rank = rrank; 7537 } 7538 for (r = 0; r < 3; ++r, ++m) { 7539 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 7540 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 7541 remotePointsNew[m].rank = rrank; 7542 } 7543 } else if ((p >= fMax) && (p < fEnd)) { 7544 /* Hybrid faces add new faces and edges */ 7545 for (r = 0; r < 2; ++r, ++m) { 7546 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 7547 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; 7548 remotePointsNew[m].rank = rrank; 7549 } 7550 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 7551 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]); 7552 remotePointsNew[m].rank = rrank; 7553 ++m; 7554 } else if ((p >= cStart) && (p < cMax)) { 7555 /* Interior cells add new cells, faces, and edges */ 7556 for (r = 0; r < 8; ++r, ++m) { 7557 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7558 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7559 remotePointsNew[m].rank = rrank; 7560 } 7561 for (r = 0; r < 8; ++r, ++m) { 7562 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 7563 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 7564 remotePointsNew[m].rank = rrank; 7565 } 7566 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 7567 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; 7568 remotePointsNew[m].rank = rrank; 7569 ++m; 7570 } else if ((p >= cMax) && (p < cEnd)) { 7571 /* Hybrid cells add new cells and faces */ 7572 for (r = 0; r < 4; ++r, ++m) { 7573 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7574 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7575 remotePointsNew[m].rank = rrank; 7576 } 7577 for (r = 0; r < 3; ++r, ++m) { 7578 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 7579 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; 7580 remotePointsNew[m].rank = rrank; 7581 } 7582 } 7583 break; 7584 case REFINER_SIMPLEX_TO_HEX_3D: 7585 if ((p >= vStart) && (p < vEnd)) { 7586 /* Interior vertices stay the same */ 7587 localPointsNew[m] = vStartNew + (p - vStart); 7588 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7589 remotePointsNew[m].rank = rrank; 7590 ++m; 7591 } else if ((p >= eStart) && (p < eEnd)) { 7592 /* Interior edges add new edges and vertex */ 7593 for (r = 0; r < 2; ++r, ++m) { 7594 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7595 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7596 remotePointsNew[m].rank = rrank; 7597 } 7598 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7599 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7600 remotePointsNew[m].rank = rrank; 7601 ++m; 7602 } else if ((p >= fStart) && (p < fEnd)) { 7603 /* Interior faces add new faces, edges and a vertex */ 7604 for (r = 0; r < 3; ++r, ++m) { 7605 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 7606 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 7607 remotePointsNew[m].rank = rrank; 7608 } 7609 for (r = 0; r < 3; ++r, ++m) { 7610 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 7611 remotePointsNew[m].index = reStartNew[n] + (rdepthSizeOld[n*(depth+1)+1])*2 + (rp - rfStart[n])*3 + r; 7612 remotePointsNew[m].rank = rrank; 7613 } 7614 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 7615 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 7616 remotePointsNew[m].rank = rrank; 7617 ++m; 7618 } else if ((p >= cStart) && (p < cEnd)) { 7619 /* Interior cells add new cells, faces, edges, and a vertex */ 7620 for (r = 0; r < 4; ++r, ++m) { 7621 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7622 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7623 remotePointsNew[m].rank = rrank; 7624 } 7625 for (r = 0; r < 6; ++r, ++m) { 7626 localPointsNew[m] = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 7627 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*6 + r; 7628 remotePointsNew[m].rank = rrank; 7629 } 7630 for (r = 0; r < 4; ++r, ++m) { 7631 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 7632 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*4 + r; 7633 remotePointsNew[m].rank = rrank; 7634 } 7635 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 7636 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 7637 remotePointsNew[m].rank = rrank; 7638 ++m; 7639 } 7640 break; 7641 case REFINER_HEX_3D: 7642 case REFINER_HYBRID_HEX_3D: 7643 if ((p >= vStart) && (p < vEnd)) { 7644 /* Interior vertices stay the same */ 7645 localPointsNew[m] = vStartNew + (p - vStart); 7646 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7647 remotePointsNew[m].rank = rrank; 7648 ++m; 7649 } else if ((p >= eStart) && (p < eMax)) { 7650 /* Interior edges add new edges and vertex */ 7651 for (r = 0; r < 2; ++r, ++m) { 7652 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7653 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7654 remotePointsNew[m].rank = rrank; 7655 } 7656 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7657 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7658 remotePointsNew[m].rank = rrank; 7659 ++m; 7660 } else if ((p >= eMax) && (p < eEnd)) { 7661 /* Hybrid edges stay the same */ 7662 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 7663 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]); 7664 remotePointsNew[m].rank = rrank; 7665 ++m; 7666 } else if ((p >= fStart) && (p < fMax)) { 7667 /* Interior faces add new faces, edges, and vertex */ 7668 for (r = 0; r < 4; ++r, ++m) { 7669 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7670 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7671 remotePointsNew[m].rank = rrank; 7672 } 7673 for (r = 0; r < 4; ++r, ++m) { 7674 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 7675 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 7676 remotePointsNew[m].rank = rrank; 7677 } 7678 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 7679 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 7680 remotePointsNew[m].rank = rrank; 7681 ++m; 7682 } else if ((p >= fMax) && (p < fEnd)) { 7683 /* Hybrid faces add new faces and edges */ 7684 for (r = 0; r < 2; ++r, ++m) { 7685 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 7686 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; 7687 remotePointsNew[m].rank = rrank; 7688 } 7689 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 7690 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]); 7691 remotePointsNew[m].rank = rrank; 7692 ++m; 7693 } else if ((p >= cStart) && (p < cMax)) { 7694 /* Interior cells add new cells, faces, edges, and vertex */ 7695 for (r = 0; r < 8; ++r, ++m) { 7696 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7697 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7698 remotePointsNew[m].rank = rrank; 7699 } 7700 for (r = 0; r < 12; ++r, ++m) { 7701 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 7702 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 7703 remotePointsNew[m].rank = rrank; 7704 } 7705 for (r = 0; r < 6; ++r, ++m) { 7706 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 7707 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; 7708 remotePointsNew[m].rank = rrank; 7709 } 7710 for (r = 0; r < 1; ++r, ++m) { 7711 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 7712 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 7713 remotePointsNew[m].rank = rrank; 7714 } 7715 } else if ((p >= cMax) && (p < cEnd)) { 7716 /* Hybrid cells add new cells, faces, and edges */ 7717 for (r = 0; r < 4; ++r, ++m) { 7718 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7719 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7720 remotePointsNew[m].rank = rrank; 7721 } 7722 for (r = 0; r < 4; ++r, ++m) { 7723 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 7724 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; 7725 remotePointsNew[m].rank = rrank; 7726 } 7727 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 7728 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]); 7729 remotePointsNew[m].rank = rrank; 7730 ++m; 7731 } 7732 break; 7733 default: 7734 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7735 } 7736 } 7737 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 7738 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 7739 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 7740 { 7741 PetscSFNode *rp, *rtmp; 7742 PetscInt *lp, *idx, *ltmp, i; 7743 7744 /* SF needs sorted leaves to correct calculate Gather */ 7745 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 7746 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 7747 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 7748 for (i = 0; i < numLeavesNew; ++i) { 7749 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); 7750 idx[i] = i; 7751 } 7752 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 7753 for (i = 0; i < numLeavesNew; ++i) { 7754 lp[i] = localPointsNew[idx[i]]; 7755 rp[i] = remotePointsNew[idx[i]]; 7756 } 7757 ltmp = localPointsNew; 7758 localPointsNew = lp; 7759 rtmp = remotePointsNew; 7760 remotePointsNew = rp; 7761 ierr = PetscFree(idx);CHKERRQ(ierr); 7762 ierr = PetscFree(ltmp);CHKERRQ(ierr); 7763 ierr = PetscFree(rtmp);CHKERRQ(ierr); 7764 } 7765 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 7766 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 7767 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 7768 PetscFunctionReturn(0); 7769 } 7770 7771 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 7772 { 7773 PetscInt numLabels, l; 7774 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 7775 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7776 PetscErrorCode ierr; 7777 7778 PetscFunctionBegin; 7779 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7780 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 7781 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7782 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7783 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 7784 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7785 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 7786 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7787 switch (refiner) { 7788 case REFINER_NOOP: 7789 case REFINER_SIMPLEX_1D: 7790 case REFINER_SIMPLEX_2D: 7791 case REFINER_SIMPLEX_TO_HEX_2D: 7792 case REFINER_HEX_2D: 7793 case REFINER_SIMPLEX_3D: 7794 case REFINER_HEX_3D: 7795 case REFINER_SIMPLEX_TO_HEX_3D: 7796 break; 7797 case REFINER_HYBRID_SIMPLEX_3D: 7798 case REFINER_HYBRID_HEX_3D: 7799 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 7800 case REFINER_HYBRID_SIMPLEX_2D: 7801 case REFINER_HYBRID_HEX_2D: 7802 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 7803 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 7804 break; 7805 default: 7806 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7807 } 7808 for (l = 0; l < numLabels; ++l) { 7809 DMLabel label, labelNew; 7810 const char *lname; 7811 PetscBool isDepth; 7812 IS valueIS; 7813 const PetscInt *values; 7814 PetscInt defVal; 7815 PetscInt numValues, val; 7816 7817 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 7818 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 7819 if (isDepth) continue; 7820 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 7821 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 7822 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 7823 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 7824 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 7825 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 7826 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 7827 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 7828 for (val = 0; val < numValues; ++val) { 7829 IS pointIS; 7830 const PetscInt *points; 7831 PetscInt numPoints, n; 7832 7833 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 7834 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 7835 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 7836 /* Ensure refined label is created with same number of strata as 7837 * original (even if no entries here). */ 7838 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 7839 for (n = 0; n < numPoints; ++n) { 7840 const PetscInt p = points[n]; 7841 switch (refiner) { 7842 case REFINER_SIMPLEX_1D: 7843 if ((p >= vStart) && (p < vEnd)) { 7844 /* Old vertices stay the same */ 7845 newp = vStartNew + (p - vStart); 7846 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7847 } else if ((p >= cStart) && (p < cEnd)) { 7848 /* Old cells add new cells and vertex */ 7849 newp = vStartNew + (vEnd - vStart) + (p - cStart); 7850 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7851 for (r = 0; r < 2; ++r) { 7852 newp = cStartNew + (p - cStart)*2 + r; 7853 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7854 } 7855 } 7856 break; 7857 case REFINER_SIMPLEX_2D: 7858 if ((p >= vStart) && (p < vEnd)) { 7859 /* Old vertices stay the same */ 7860 newp = vStartNew + (p - vStart); 7861 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7862 } else if ((p >= fStart) && (p < fEnd)) { 7863 /* Old faces add new faces and vertex */ 7864 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7865 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7866 for (r = 0; r < 2; ++r) { 7867 newp = fStartNew + (p - fStart)*2 + r; 7868 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7869 } 7870 } else if ((p >= cStart) && (p < cEnd)) { 7871 /* Old cells add new cells and interior faces */ 7872 for (r = 0; r < 4; ++r) { 7873 newp = cStartNew + (p - cStart)*4 + r; 7874 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7875 } 7876 for (r = 0; r < 3; ++r) { 7877 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7878 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7879 } 7880 } 7881 break; 7882 case REFINER_SIMPLEX_TO_HEX_2D: 7883 if ((p >= vStart) && (p < vEnd)) { 7884 /* Old vertices stay the same */ 7885 newp = vStartNew + (p - vStart); 7886 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7887 } else if ((p >= fStart) && (p < fEnd)) { 7888 /* Old faces add new faces and vertex */ 7889 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7890 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7891 for (r = 0; r < 2; ++r) { 7892 newp = fStartNew + (p - fStart)*2 + r; 7893 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7894 } 7895 } else if ((p >= cStart) && (p < cEnd)) { 7896 /* Old cells add new cells, interior faces, and a vertex */ 7897 for (r = 0; r < 3; ++r) { 7898 newp = cStartNew + (p - cStart)*3 + r; 7899 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7900 } 7901 for (r = 0; r < 3; ++r) { 7902 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7903 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7904 } 7905 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 7906 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7907 } 7908 break; 7909 case REFINER_HEX_2D: 7910 if ((p >= vStart) && (p < vEnd)) { 7911 /* Old vertices stay the same */ 7912 newp = vStartNew + (p - vStart); 7913 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7914 } else if ((p >= fStart) && (p < fEnd)) { 7915 /* Old faces add new faces and vertex */ 7916 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7917 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7918 for (r = 0; r < 2; ++r) { 7919 newp = fStartNew + (p - fStart)*2 + r; 7920 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7921 } 7922 } else if ((p >= cStart) && (p < cEnd)) { 7923 /* Old cells add new cells and interior faces and vertex */ 7924 for (r = 0; r < 4; ++r) { 7925 newp = cStartNew + (p - cStart)*4 + r; 7926 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7927 } 7928 for (r = 0; r < 4; ++r) { 7929 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 7930 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7931 } 7932 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7933 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7934 } 7935 break; 7936 case REFINER_HYBRID_SIMPLEX_2D: 7937 if ((p >= vStart) && (p < vEnd)) { 7938 /* Old vertices stay the same */ 7939 newp = vStartNew + (p - vStart); 7940 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7941 } else if ((p >= fStart) && (p < fMax)) { 7942 /* Old interior faces add new faces and vertex */ 7943 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7944 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7945 for (r = 0; r < 2; ++r) { 7946 newp = fStartNew + (p - fStart)*2 + r; 7947 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7948 } 7949 } else if ((p >= fMax) && (p < fEnd)) { 7950 /* Old hybrid faces stay the same */ 7951 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 7952 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7953 } else if ((p >= cStart) && (p < cMax)) { 7954 /* Old interior cells add new cells and interior faces */ 7955 for (r = 0; r < 4; ++r) { 7956 newp = cStartNew + (p - cStart)*4 + r; 7957 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7958 } 7959 for (r = 0; r < 3; ++r) { 7960 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7961 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7962 } 7963 } else if ((p >= cMax) && (p < cEnd)) { 7964 /* Old hybrid cells add new cells and hybrid face */ 7965 for (r = 0; r < 2; ++r) { 7966 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 7967 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7968 } 7969 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 7970 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7971 } 7972 break; 7973 case REFINER_HYBRID_HEX_2D: 7974 if ((p >= vStart) && (p < vEnd)) { 7975 /* Old vertices stay the same */ 7976 newp = vStartNew + (p - vStart); 7977 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7978 } else if ((p >= fStart) && (p < fMax)) { 7979 /* Old interior faces add new faces and vertex */ 7980 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7981 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7982 for (r = 0; r < 2; ++r) { 7983 newp = fStartNew + (p - fStart)*2 + r; 7984 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7985 } 7986 } else if ((p >= fMax) && (p < fEnd)) { 7987 /* Old hybrid faces stay the same */ 7988 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 7989 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7990 } else if ((p >= cStart) && (p < cMax)) { 7991 /* Old interior cells add new cells, interior faces, and vertex */ 7992 for (r = 0; r < 4; ++r) { 7993 newp = cStartNew + (p - cStart)*4 + r; 7994 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7995 } 7996 for (r = 0; r < 4; ++r) { 7997 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 7998 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7999 } 8000 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 8001 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8002 } else if ((p >= cMax) && (p < cEnd)) { 8003 /* Old hybrid cells add new cells and hybrid face */ 8004 for (r = 0; r < 2; ++r) { 8005 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 8006 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8007 } 8008 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 8009 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8010 } 8011 break; 8012 case REFINER_SIMPLEX_3D: 8013 if ((p >= vStart) && (p < vEnd)) { 8014 /* Old vertices stay the same */ 8015 newp = vStartNew + (p - vStart); 8016 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8017 } else if ((p >= eStart) && (p < eEnd)) { 8018 /* Old edges add new edges and vertex */ 8019 for (r = 0; r < 2; ++r) { 8020 newp = eStartNew + (p - eStart)*2 + r; 8021 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8022 } 8023 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8024 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8025 } else if ((p >= fStart) && (p < fEnd)) { 8026 /* Old faces add new faces and edges */ 8027 for (r = 0; r < 4; ++r) { 8028 newp = fStartNew + (p - fStart)*4 + r; 8029 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8030 } 8031 for (r = 0; r < 3; ++r) { 8032 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 8033 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8034 } 8035 } else if ((p >= cStart) && (p < cEnd)) { 8036 /* Old cells add new cells and interior faces and edges */ 8037 for (r = 0; r < 8; ++r) { 8038 newp = cStartNew + (p - cStart)*8 + r; 8039 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8040 } 8041 for (r = 0; r < 8; ++r) { 8042 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 8043 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8044 } 8045 for (r = 0; r < 1; ++r) { 8046 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 8047 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8048 } 8049 } 8050 break; 8051 case REFINER_SIMPLEX_TO_HEX_3D: 8052 if ((p >= vStart) && (p < vEnd)) { 8053 /* Old vertices stay the same */ 8054 newp = vStartNew + (p - vStart); 8055 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8056 } else if ((p >= eStart) && (p < eEnd)) { 8057 /* Old edges add new edges and vertex */ 8058 for (r = 0; r < 2; ++r) { 8059 newp = eStartNew + (p - eStart)*2 + r; 8060 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8061 } 8062 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8063 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8064 } else if ((p >= fStart) && (p < fEnd)) { 8065 /* Old faces add new faces, edges and a vertex */ 8066 for (r = 0; r < 3; ++r) { 8067 newp = fStartNew + (p - fStart)*3 + r; 8068 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8069 } 8070 for (r = 0; r < 3; ++r) { 8071 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 8072 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8073 } 8074 } else if ((p >= cStart) && (p < cEnd)) { 8075 /* Old cells add new cells and interior faces and edges and a vertex */ 8076 for (r = 0; r < 4; ++r) { 8077 newp = cStartNew + (p - cStart)*4 + r; 8078 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8079 } 8080 for (r = 0; r < 6; ++r) { 8081 newp = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 8082 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8083 } 8084 for (r = 0; r < 4; ++r) { 8085 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 8086 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8087 } 8088 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + p - cStart; 8089 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8090 } 8091 break; 8092 case REFINER_HYBRID_SIMPLEX_3D: 8093 if ((p >= vStart) && (p < vEnd)) { 8094 /* Interior vertices stay the same */ 8095 newp = vStartNew + (p - vStart); 8096 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8097 } else if ((p >= eStart) && (p < eMax)) { 8098 /* Interior edges add new edges and vertex */ 8099 for (r = 0; r < 2; ++r) { 8100 newp = eStartNew + (p - eStart)*2 + r; 8101 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8102 } 8103 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8104 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8105 } else if ((p >= eMax) && (p < eEnd)) { 8106 /* Hybrid edges stay the same */ 8107 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 8108 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8109 } else if ((p >= fStart) && (p < fMax)) { 8110 /* Interior faces add new faces and edges */ 8111 for (r = 0; r < 4; ++r) { 8112 newp = fStartNew + (p - fStart)*4 + r; 8113 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8114 } 8115 for (r = 0; r < 3; ++r) { 8116 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 8117 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8118 } 8119 } else if ((p >= fMax) && (p < fEnd)) { 8120 /* Hybrid faces add new faces and edges */ 8121 for (r = 0; r < 2; ++r) { 8122 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 8123 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8124 } 8125 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 8126 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8127 } else if ((p >= cStart) && (p < cMax)) { 8128 /* Interior cells add new cells, faces, and edges */ 8129 for (r = 0; r < 8; ++r) { 8130 newp = cStartNew + (p - cStart)*8 + r; 8131 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8132 } 8133 for (r = 0; r < 8; ++r) { 8134 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 8135 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8136 } 8137 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 8138 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8139 } else if ((p >= cMax) && (p < cEnd)) { 8140 /* Hybrid cells add new cells and faces */ 8141 for (r = 0; r < 4; ++r) { 8142 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 8143 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8144 } 8145 for (r = 0; r < 3; ++r) { 8146 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 8147 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8148 } 8149 } 8150 break; 8151 case REFINER_HEX_3D: 8152 if ((p >= vStart) && (p < vEnd)) { 8153 /* Old vertices stay the same */ 8154 newp = vStartNew + (p - vStart); 8155 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8156 } else if ((p >= eStart) && (p < eEnd)) { 8157 /* Old edges add new edges and vertex */ 8158 for (r = 0; r < 2; ++r) { 8159 newp = eStartNew + (p - eStart)*2 + r; 8160 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8161 } 8162 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8163 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8164 } else if ((p >= fStart) && (p < fEnd)) { 8165 /* Old faces add new faces, edges, and vertex */ 8166 for (r = 0; r < 4; ++r) { 8167 newp = fStartNew + (p - fStart)*4 + r; 8168 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8169 } 8170 for (r = 0; r < 4; ++r) { 8171 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 8172 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8173 } 8174 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 8175 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8176 } else if ((p >= cStart) && (p < cEnd)) { 8177 /* Old cells add new cells, faces, edges, and vertex */ 8178 for (r = 0; r < 8; ++r) { 8179 newp = cStartNew + (p - cStart)*8 + r; 8180 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8181 } 8182 for (r = 0; r < 12; ++r) { 8183 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 8184 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8185 } 8186 for (r = 0; r < 6; ++r) { 8187 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 8188 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8189 } 8190 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 8191 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8192 } 8193 break; 8194 case REFINER_HYBRID_HEX_3D: 8195 if ((p >= vStart) && (p < vEnd)) { 8196 /* Interior vertices stay the same */ 8197 newp = vStartNew + (p - vStart); 8198 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8199 } else if ((p >= eStart) && (p < eMax)) { 8200 /* Interior edges add new edges and vertex */ 8201 for (r = 0; r < 2; ++r) { 8202 newp = eStartNew + (p - eStart)*2 + r; 8203 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8204 } 8205 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8206 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8207 } else if ((p >= eMax) && (p < eEnd)) { 8208 /* Hybrid edges stay the same */ 8209 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 8210 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8211 } else if ((p >= fStart) && (p < fMax)) { 8212 /* Interior faces add new faces, edges, and vertex */ 8213 for (r = 0; r < 4; ++r) { 8214 newp = fStartNew + (p - fStart)*4 + r; 8215 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8216 } 8217 for (r = 0; r < 4; ++r) { 8218 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 8219 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8220 } 8221 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 8222 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8223 } else if ((p >= fMax) && (p < fEnd)) { 8224 /* Hybrid faces add new faces and edges */ 8225 for (r = 0; r < 2; ++r) { 8226 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 8227 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8228 } 8229 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 8230 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8231 } else if ((p >= cStart) && (p < cMax)) { 8232 /* Interior cells add new cells, faces, edges, and vertex */ 8233 for (r = 0; r < 8; ++r) { 8234 newp = cStartNew + (p - cStart)*8 + r; 8235 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8236 } 8237 for (r = 0; r < 12; ++r) { 8238 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 8239 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8240 } 8241 for (r = 0; r < 6; ++r) { 8242 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 8243 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8244 } 8245 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 8246 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8247 } else if ((p >= cMax) && (p < cEnd)) { 8248 /* Hybrid cells add new cells, faces, and edges */ 8249 for (r = 0; r < 4; ++r) { 8250 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 8251 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8252 } 8253 for (r = 0; r < 4; ++r) { 8254 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 8255 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8256 } 8257 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 8258 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8259 } 8260 break; 8261 default: 8262 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 8263 } 8264 } 8265 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 8266 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 8267 } 8268 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 8269 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 8270 if (0) { 8271 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 8272 } 8273 } 8274 PetscFunctionReturn(0); 8275 } 8276 8277 /* This will only work for interpolated meshes */ 8278 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 8279 { 8280 DM rdm; 8281 PetscInt *depthSize; 8282 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 8283 PetscErrorCode ierr; 8284 8285 PetscFunctionBegin; 8286 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 8287 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 8288 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8289 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 8290 /* Calculate number of new points of each depth */ 8291 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8292 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 8293 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 8294 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 8295 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 8296 /* Step 1: Set chart */ 8297 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 8298 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 8299 /* Step 2: Set cone/support sizes */ 8300 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8301 /* Step 3: Setup refined DM */ 8302 ierr = DMSetUp(rdm);CHKERRQ(ierr); 8303 /* Step 4: Set cones and supports */ 8304 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8305 /* Step 5: Stratify */ 8306 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 8307 /* Step 6: Create pointSF */ 8308 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8309 /* Step 7: Create labels */ 8310 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8311 /* Step 8: Set coordinates */ 8312 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8313 ierr = PetscFree(depthSize);CHKERRQ(ierr); 8314 8315 *dmRefined = rdm; 8316 PetscFunctionReturn(0); 8317 } 8318 8319 /*@ 8320 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 8321 8322 Input Parameter: 8323 . dm - The coarse DM 8324 8325 Output Parameter: 8326 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 8327 8328 Level: developer 8329 8330 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 8331 @*/ 8332 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 8333 { 8334 CellRefiner cellRefiner; 8335 PetscInt *depthSize, *fpoints; 8336 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8337 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 8338 PetscErrorCode ierr; 8339 8340 PetscFunctionBegin; 8341 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8342 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 8343 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8344 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 8345 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 8346 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 8347 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8348 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 8349 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 8350 switch (cellRefiner) { 8351 case REFINER_SIMPLEX_1D: 8352 case REFINER_SIMPLEX_2D: 8353 case REFINER_HYBRID_SIMPLEX_2D: 8354 case REFINER_HEX_2D: 8355 case REFINER_HYBRID_HEX_2D: 8356 case REFINER_SIMPLEX_3D: 8357 case REFINER_HYBRID_SIMPLEX_3D: 8358 case REFINER_HEX_3D: 8359 case REFINER_HYBRID_HEX_3D: 8360 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 8361 break; 8362 default: 8363 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 8364 } 8365 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 8366 ierr = PetscFree(depthSize);CHKERRQ(ierr); 8367 PetscFunctionReturn(0); 8368 } 8369 8370 /*@ 8371 DMPlexSetRefinementUniform - Set the flag for uniform refinement 8372 8373 Input Parameters: 8374 + dm - The DM 8375 - refinementUniform - The flag for uniform refinement 8376 8377 Level: developer 8378 8379 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8380 @*/ 8381 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 8382 { 8383 DM_Plex *mesh = (DM_Plex*) dm->data; 8384 8385 PetscFunctionBegin; 8386 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8387 mesh->refinementUniform = refinementUniform; 8388 PetscFunctionReturn(0); 8389 } 8390 8391 /*@ 8392 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 8393 8394 Input Parameter: 8395 . dm - The DM 8396 8397 Output Parameter: 8398 . refinementUniform - The flag for uniform refinement 8399 8400 Level: developer 8401 8402 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8403 @*/ 8404 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 8405 { 8406 DM_Plex *mesh = (DM_Plex*) dm->data; 8407 8408 PetscFunctionBegin; 8409 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8410 PetscValidPointer(refinementUniform, 2); 8411 *refinementUniform = mesh->refinementUniform; 8412 PetscFunctionReturn(0); 8413 } 8414 8415 /*@ 8416 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 8417 8418 Input Parameters: 8419 + dm - The DM 8420 - refinementLimit - The maximum cell volume in the refined mesh 8421 8422 Level: developer 8423 8424 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 8425 @*/ 8426 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 8427 { 8428 DM_Plex *mesh = (DM_Plex*) dm->data; 8429 8430 PetscFunctionBegin; 8431 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8432 mesh->refinementLimit = refinementLimit; 8433 PetscFunctionReturn(0); 8434 } 8435 8436 /*@ 8437 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 8438 8439 Input Parameter: 8440 . dm - The DM 8441 8442 Output Parameter: 8443 . refinementLimit - The maximum cell volume in the refined mesh 8444 8445 Level: developer 8446 8447 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 8448 @*/ 8449 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 8450 { 8451 DM_Plex *mesh = (DM_Plex*) dm->data; 8452 8453 PetscFunctionBegin; 8454 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8455 PetscValidPointer(refinementLimit, 2); 8456 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 8457 *refinementLimit = mesh->refinementLimit; 8458 PetscFunctionReturn(0); 8459 } 8460 8461 /*@ 8462 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 8463 8464 Input Parameters: 8465 + dm - The DM 8466 - refinementFunc - Function giving the maximum cell volume in the refined mesh 8467 8468 Note: The calling sequence is refinementFunc(coords, limit) 8469 $ coords - Coordinates of the current point, usually a cell centroid 8470 $ limit - The maximum cell volume for a cell containing this point 8471 8472 Level: developer 8473 8474 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8475 @*/ 8476 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 8477 { 8478 DM_Plex *mesh = (DM_Plex*) dm->data; 8479 8480 PetscFunctionBegin; 8481 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8482 mesh->refinementFunc = refinementFunc; 8483 PetscFunctionReturn(0); 8484 } 8485 8486 /*@ 8487 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 8488 8489 Input Parameter: 8490 . dm - The DM 8491 8492 Output Parameter: 8493 . refinementFunc - Function giving the maximum cell volume in the refined mesh 8494 8495 Note: The calling sequence is refinementFunc(coords, limit) 8496 $ coords - Coordinates of the current point, usually a cell centroid 8497 $ limit - The maximum cell volume for a cell containing this point 8498 8499 Level: developer 8500 8501 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8502 @*/ 8503 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 8504 { 8505 DM_Plex *mesh = (DM_Plex*) dm->data; 8506 8507 PetscFunctionBegin; 8508 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8509 PetscValidPointer(refinementFunc, 2); 8510 *refinementFunc = mesh->refinementFunc; 8511 PetscFunctionReturn(0); 8512 } 8513 8514 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 8515 { 8516 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 8517 PetscErrorCode ierr; 8518 8519 PetscFunctionBegin; 8520 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8521 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8522 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 8523 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 8524 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 8525 switch (dim) { 8526 case 1: 8527 switch (coneSize) { 8528 case 2: 8529 *cellRefiner = REFINER_SIMPLEX_1D; 8530 break; 8531 default: 8532 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8533 } 8534 break; 8535 case 2: 8536 switch (coneSize) { 8537 case 3: 8538 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 8539 else *cellRefiner = REFINER_SIMPLEX_2D; 8540 break; 8541 case 4: 8542 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 8543 else *cellRefiner = REFINER_HEX_2D; 8544 break; 8545 default: 8546 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8547 } 8548 break; 8549 case 3: 8550 switch (coneSize) { 8551 case 4: 8552 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 8553 else *cellRefiner = REFINER_SIMPLEX_3D; 8554 break; 8555 case 6: 8556 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 8557 else *cellRefiner = REFINER_HEX_3D; 8558 break; 8559 default: 8560 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8561 } 8562 break; 8563 default: 8564 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 8565 } 8566 PetscFunctionReturn(0); 8567 } 8568 8569 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 8570 { 8571 PetscBool isUniform; 8572 PetscErrorCode ierr; 8573 8574 PetscFunctionBegin; 8575 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 8576 if (isUniform) { 8577 CellRefiner cellRefiner; 8578 PetscBool localized; 8579 8580 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 8581 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 8582 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 8583 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 8584 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 8585 } else { 8586 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 8587 } 8588 PetscFunctionReturn(0); 8589 } 8590 8591 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 8592 { 8593 DM cdm = dm; 8594 PetscInt r; 8595 PetscBool isUniform, localized; 8596 PetscErrorCode ierr; 8597 8598 PetscFunctionBegin; 8599 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 8600 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 8601 if (isUniform) { 8602 for (r = 0; r < nlevels; ++r) { 8603 CellRefiner cellRefiner; 8604 8605 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 8606 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 8607 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 8608 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 8609 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 8610 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 8611 cdm = dmRefined[r]; 8612 } 8613 } else { 8614 for (r = 0; r < nlevels; ++r) { 8615 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 8616 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 8617 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 8618 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 8619 cdm = dmRefined[r]; 8620 } 8621 } 8622 PetscFunctionReturn(0); 8623 } 8624