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 = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 6501 /* Determine if we need to localize coordinates when generating them */ 6502 if (isperiodic && !maxCell) { 6503 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 6504 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 6505 } 6506 if (isperiodic) { 6507 ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr); 6508 ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr); 6509 ierr = PetscOptionsEnd();CHKERRQ(ierr); 6510 if (localize) { 6511 ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 6512 } 6513 } 6514 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 6515 6516 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 6517 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 6518 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 6519 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 6520 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 6521 6522 if (localize) { 6523 PetscInt p, r, newp, *pi; 6524 6525 /* New coordinates will be already localized on the cell */ 6526 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 6527 6528 /* We need the parentId to properly localize coordinates */ 6529 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 6530 switch (refiner) { 6531 case REFINER_NOOP: 6532 break; 6533 case REFINER_SIMPLEX_1D: 6534 for (p = cStart; p < cEnd; ++p) { 6535 for (r = 0; r < 2; ++r) { 6536 newp = (p - cStart)*2 + r; 6537 pi[newp] = p; 6538 } 6539 } 6540 break; 6541 case REFINER_SIMPLEX_2D: 6542 for (p = cStart; p < cEnd; ++p) { 6543 for (r = 0; r < 4; ++r) { 6544 newp = (p - cStart)*4 + r; 6545 pi[newp] = p; 6546 } 6547 } 6548 break; 6549 case REFINER_HEX_2D: 6550 for (p = cStart; p < cEnd; ++p) { 6551 for (r = 0; r < 4; ++r) { 6552 newp = (p - cStart)*4 + r; 6553 pi[newp] = p; 6554 } 6555 } 6556 break; 6557 case REFINER_SIMPLEX_TO_HEX_2D: 6558 for (p = cStart; p < cEnd; ++p) { 6559 for (r = 0; r < 3; ++r) { 6560 newp = (p - cStart)*3 + r; 6561 pi[newp] = p; 6562 } 6563 } 6564 break; 6565 case REFINER_HYBRID_SIMPLEX_2D: 6566 for (p = cStart; p < cMax; ++p) { 6567 for (r = 0; r < 4; ++r) { 6568 newp = (p - cStart)*4 + r; 6569 pi[newp] = p; 6570 } 6571 } 6572 for (p = cMax; p < cEnd; ++p) { 6573 for (r = 0; r < 2; ++r) { 6574 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 6575 pi[newp] = p; 6576 } 6577 } 6578 break; 6579 case REFINER_HYBRID_HEX_2D: 6580 for (p = cStart; p < cMax; ++p) { 6581 for (r = 0; r < 4; ++r) { 6582 newp = (p - cStart)*4 + r; 6583 pi[newp] = p; 6584 } 6585 } 6586 for (p = cMax; p < cEnd; ++p) { 6587 for (r = 0; r < 2; ++r) { 6588 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 6589 pi[newp] = p; 6590 } 6591 } 6592 break; 6593 case REFINER_SIMPLEX_3D: 6594 for (p = cStart; p < cEnd; ++p) { 6595 for (r = 0; r < 8; ++r) { 6596 newp = (p - cStart)*8 + r; 6597 pi[newp] = p; 6598 } 6599 } 6600 break; 6601 case REFINER_HYBRID_SIMPLEX_3D: 6602 for (p = cStart; p < cMax; ++p) { 6603 for (r = 0; r < 8; ++r) { 6604 newp = (p - cStart)*8 + r; 6605 pi[newp] = p; 6606 } 6607 } 6608 for (p = cMax; p < cEnd; ++p) { 6609 for (r = 0; r < 4; ++r) { 6610 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 6611 pi[newp] = p; 6612 } 6613 } 6614 break; 6615 case REFINER_SIMPLEX_TO_HEX_3D: 6616 for (p = cStart; p < cEnd; ++p) { 6617 for (r = 0; r < 4; ++r) { 6618 newp = (p - cStart)*4 + r; 6619 pi[newp] = p; 6620 } 6621 } 6622 break; 6623 case REFINER_HEX_3D: 6624 for (p = cStart; p < cEnd; ++p) { 6625 for (r = 0; r < 8; ++r) { 6626 newp = (p - cStart)*8 + r; 6627 pi[newp] = p; 6628 } 6629 } 6630 break; 6631 case REFINER_HYBRID_HEX_3D: 6632 for (p = cStart; p < cMax; ++p) { 6633 for (r = 0; r < 8; ++r) { 6634 newp = (p - cStart)*8 + r; 6635 pi[newp] = p; 6636 } 6637 } 6638 for (p = cMax; p < cEnd; ++p) { 6639 for (r = 0; r < 4; ++r) { 6640 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 6641 pi[newp] = p; 6642 } 6643 } 6644 break; 6645 default: 6646 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6647 } 6648 parentId = pi; 6649 } else { 6650 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 6651 } 6652 if (cMax < 0) cMax = cEnd; 6653 if (fMax < 0) fMax = fEnd; 6654 if (eMax < 0) eMax = eEnd; 6655 6656 /* All vertices have the spaceDim coordinates */ 6657 if (localize) { 6658 PetscInt c; 6659 6660 for (c = cStartNew; c < cEndNew; ++c) { 6661 PetscInt *cone = NULL; 6662 PetscInt closureSize, coneSize = 0, p, pdof; 6663 6664 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 6665 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 6666 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6667 for (p = 0; p < closureSize*2; p += 2) { 6668 const PetscInt point = cone[p]; 6669 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 6670 } 6671 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6672 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 6673 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 6674 } 6675 } 6676 } 6677 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 6678 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 6679 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 6680 } 6681 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 6682 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 6683 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 6684 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 6685 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 6686 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 6687 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 6688 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 6689 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 6690 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 6691 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 6692 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 6693 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 6694 6695 switch (refiner) { 6696 case REFINER_NOOP: break; 6697 case REFINER_SIMPLEX_TO_HEX_3D: 6698 case REFINER_HEX_3D: 6699 case REFINER_HYBRID_HEX_3D: 6700 /* Face vertices have the average of corner coordinates */ 6701 for (f = fStart; f < fMax; ++f) { 6702 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6703 PetscInt *cone = NULL; 6704 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 6705 6706 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6707 for (p = 0; p < closureSize*2; p += 2) { 6708 const PetscInt point = cone[p]; 6709 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6710 } 6711 if (localize) { 6712 const PetscInt *support = NULL; 6713 PetscInt *rStar = NULL; 6714 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 6715 PetscBool cellfound = PETSC_FALSE; 6716 6717 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6718 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 6719 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 6720 /* Compute average of coordinates for each cell sharing the face */ 6721 for (s = 0; s < supportSize; ++s) { 6722 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 6723 PetscInt *cellCone = NULL; 6724 PetscInt cellClosureSize, cellConeSize = 0, cdof; 6725 const PetscInt cell = support[s]; 6726 PetscBool copyoff = PETSC_FALSE; 6727 6728 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6729 for (p = 0; p < cellClosureSize*2; p += 2) { 6730 const PetscInt point = cellCone[p]; 6731 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 6732 } 6733 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 6734 if (!cdof) { /* the parent cell does not have localized coordinates */ 6735 cellfound = PETSC_TRUE; 6736 for (v = 0; v < coneSize; ++v) { 6737 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6738 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 6739 } 6740 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 6741 } else { 6742 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 6743 for (p = 0; p < coneSize; ++p) { 6744 const PetscInt tv = cone[p]; 6745 PetscInt cv, voff; 6746 PetscBool locv = PETSC_TRUE; 6747 6748 for (cv = 0; cv < cellConeSize; ++cv) { 6749 if (cellCone[cv] == tv) { 6750 ccoff[p] = spaceDim*cv + coff; 6751 break; 6752 } 6753 } 6754 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D\n",tv); 6755 6756 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 6757 for (d = 0; d < spaceDim; ++d) { 6758 coordsNewAux[d] += coords[ccoff[p]+d]; 6759 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 6760 } 6761 if (locv && !cellfound) { 6762 cellfound = PETSC_TRUE; 6763 copyoff = PETSC_TRUE; 6764 } 6765 } 6766 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 6767 6768 /* Found a valid face for the "vertex" part of the Section (physical space) 6769 i.e., a face that has at least one corner in the physical space */ 6770 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 6771 } 6772 6773 /* Localize new coordinates on each refined cell */ 6774 for (v = 0; v < rStarSize*2; v += 2) { 6775 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 6776 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 6777 const PetscInt rcell = rStar[v]; 6778 6779 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 6780 if (!rcdof) continue; 6781 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 6782 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6783 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 6784 if (rcone[p] == newv) { 6785 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 6786 break; 6787 } 6788 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 6789 } 6790 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6791 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6792 } 6793 } 6794 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6795 } 6796 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6797 if (!cellfound) { 6798 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 6799 needcoords = PETSC_TRUE; 6800 coneSize = 0; 6801 } 6802 } else { 6803 for (v = 0; v < coneSize; ++v) { 6804 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6805 } 6806 } 6807 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6808 if (coneSize) { 6809 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6810 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6811 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6812 } else { 6813 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 6814 } 6815 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6816 } 6817 case REFINER_SIMPLEX_TO_HEX_2D: 6818 case REFINER_HEX_2D: 6819 case REFINER_HYBRID_HEX_2D: 6820 case REFINER_SIMPLEX_1D: 6821 /* Cell vertices have the average of corner coordinates */ 6822 for (c = cStart; c < cMax; ++c) { 6823 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 6824 PetscInt *cone = NULL; 6825 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 6826 6827 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6828 for (p = 0; p < closureSize*2; p += 2) { 6829 const PetscInt point = cone[p]; 6830 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6831 } 6832 if (localize) { 6833 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 6834 } 6835 if (cdof) { 6836 PetscInt coff; 6837 6838 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 6839 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 6840 } else { 6841 for (v = 0; v < coneSize; ++v) { 6842 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6843 } 6844 } 6845 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6846 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6847 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6848 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6849 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6850 6851 /* Localize new coordinates on each refined cell */ 6852 if (cdof) { 6853 PetscInt *rStar = NULL, rStarSize; 6854 6855 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6856 for (v = 0; v < rStarSize*2; v += 2) { 6857 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 6858 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 6859 6860 rc = rStar[v]; 6861 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 6862 if (!rcdof) continue; 6863 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 6864 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6865 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 6866 if (cone[p] == newv) { 6867 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 6868 break; 6869 } 6870 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 6871 } 6872 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6873 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6874 } 6875 } 6876 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6877 } 6878 } 6879 case REFINER_SIMPLEX_2D: 6880 case REFINER_HYBRID_SIMPLEX_2D: 6881 case REFINER_SIMPLEX_3D: 6882 case REFINER_HYBRID_SIMPLEX_3D: 6883 /* Edge vertices have the average of endpoint coordinates */ 6884 for (e = eStart; e < eMax; ++e) { 6885 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6886 const PetscInt *cone; 6887 PetscInt coneSize, offA, offB, offnew, d; 6888 6889 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 6890 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 6891 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6892 if (localize) { 6893 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 6894 PetscInt *eStar = NULL, eStarSize; 6895 PetscInt *rStar = NULL, rStarSize; 6896 PetscBool cellfound = PETSC_FALSE; 6897 6898 offA = offB = -1; 6899 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 6900 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 6901 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 6902 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6903 for (v = 0; v < eStarSize*2; v += 2) { 6904 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 6905 PetscScalar coordsNewAux[3]; 6906 PetscInt *cellCone = NULL; 6907 PetscInt cellClosureSize, s, cv, cdof; 6908 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 6909 const PetscInt cell = eStar[v]; 6910 6911 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 6912 if (!cdof) { 6913 /* Found a valid edge for the "vertex" part of the Section */ 6914 offA = voffA; 6915 offB = voffB; 6916 cellfound = PETSC_TRUE; 6917 } else { 6918 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 6919 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6920 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 6921 const PetscInt point = cellCone[s]; 6922 if ((point >= vStart) && (point < vEnd)) { 6923 if (point == cone[0]) toffA = spaceDim*cv + coff; 6924 else if (point == cone[1]) toffB = spaceDim*cv + coff; 6925 cv++; 6926 } 6927 } 6928 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6929 for (d = 0; d < spaceDim; ++d) { 6930 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 6931 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 6932 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 6933 } 6934 /* Found a valid edge for the "vertex" part of the Section */ 6935 if (!cellfound && (locvA || locvB)) { 6936 cellfound = PETSC_TRUE; 6937 offA = toffA; 6938 offB = toffB; 6939 } 6940 } 6941 6942 /* Localize new coordinates on each refined cell */ 6943 for (s = 0; s < rStarSize*2; s += 2) { 6944 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 6945 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 6946 const PetscInt rcell = rStar[s]; 6947 6948 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 6949 if (!rcdof) continue; 6950 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 6951 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6952 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 6953 if (rcone[p] == newv) { 6954 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 6955 break; 6956 } 6957 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 6958 } 6959 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6960 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6961 } 6962 } 6963 } 6964 } 6965 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 6966 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6967 if (!cellfound) { 6968 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 6969 needcoords = PETSC_TRUE; 6970 } 6971 } else { 6972 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 6973 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 6974 } 6975 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6976 if (offA != -1 && offB != -1) { 6977 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 6978 for (d = 0; d < spaceDim; ++d) { 6979 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 6980 } 6981 } else { 6982 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 6983 } 6984 } 6985 /* Old vertices have the same coordinates */ 6986 for (v = vStart; v < vEnd; ++v) { 6987 const PetscInt newv = vStartNew + (v - vStart); 6988 PetscInt off, offnew, d; 6989 6990 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 6991 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6992 for (d = 0; d < spaceDim; ++d) { 6993 coordsNew[offnew+d] = coords[off+d]; 6994 } 6995 6996 /* Localize new coordinates on each refined cell */ 6997 if (localize) { 6998 PetscInt p; 6999 PetscInt *rStar = NULL, rStarSize; 7000 7001 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 7002 for (p = 0; p < rStarSize*2; p += 2) { 7003 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 7004 PetscScalar ocoords[3]; 7005 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 7006 7007 c = rStar[p]; 7008 oc = parentId[c-cStartNew]; 7009 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 7010 if (!cdof) continue; 7011 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 7012 if (!cdof) continue; 7013 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 7014 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7015 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 7016 if (cone[s] == v) { 7017 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 7018 break; 7019 } 7020 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 7021 } 7022 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D\n",v); 7023 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7024 7025 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 7026 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7027 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 7028 if (cone[s] == newv) { 7029 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 7030 break; 7031 } 7032 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 7033 } 7034 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 7035 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7036 } 7037 } 7038 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 7039 } 7040 } 7041 break; 7042 default: 7043 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7044 } 7045 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 7046 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 7047 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 7048 7049 /* Final reduction (if needed) if we are localizing */ 7050 if (localize) { 7051 PetscBool gred; 7052 7053 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 7054 if (gred) { 7055 DM cdm; 7056 Vec aux; 7057 PetscSF sf; 7058 const PetscScalar *lArray; 7059 PetscScalar *gArray; 7060 7061 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 7062 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 7063 ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr); 7064 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 7065 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 7066 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 7067 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 7068 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 7069 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 7070 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 7071 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 7072 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 7073 ierr = VecDestroy(&aux);CHKERRQ(ierr); 7074 } 7075 } 7076 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 7077 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 7078 ierr = PetscFree(parentId);CHKERRQ(ierr); 7079 PetscFunctionReturn(0); 7080 } 7081 7082 /*@ 7083 DMPlexCreateProcessSF - Create an SF which just has process connectivity 7084 7085 Collective on DM 7086 7087 Input Parameters: 7088 + dm - The DM 7089 - sfPoint - The PetscSF which encodes point connectivity 7090 7091 Output Parameters: 7092 + processRanks - A list of process neighbors, or NULL 7093 - sfProcess - An SF encoding the process connectivity, or NULL 7094 7095 Level: developer 7096 7097 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 7098 @*/ 7099 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 7100 { 7101 PetscInt numRoots, numLeaves, l; 7102 const PetscInt *localPoints; 7103 const PetscSFNode *remotePoints; 7104 PetscInt *localPointsNew; 7105 PetscSFNode *remotePointsNew; 7106 PetscInt *ranks, *ranksNew; 7107 PetscMPIInt size; 7108 PetscErrorCode ierr; 7109 7110 PetscFunctionBegin; 7111 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7112 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 7113 if (processRanks) {PetscValidPointer(processRanks, 3);} 7114 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 7115 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 7116 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 7117 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 7118 for (l = 0; l < numLeaves; ++l) { 7119 ranks[l] = remotePoints[l].rank; 7120 } 7121 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 7122 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 7123 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 7124 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 7125 for (l = 0; l < numLeaves; ++l) { 7126 ranksNew[l] = ranks[l]; 7127 localPointsNew[l] = l; 7128 remotePointsNew[l].index = 0; 7129 remotePointsNew[l].rank = ranksNew[l]; 7130 } 7131 ierr = PetscFree(ranks);CHKERRQ(ierr); 7132 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 7133 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 7134 if (sfProcess) { 7135 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 7136 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 7137 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 7138 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 7139 } 7140 PetscFunctionReturn(0); 7141 } 7142 7143 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 7144 { 7145 PetscSF sf, sfNew, sfProcess; 7146 IS processRanks; 7147 MPI_Datatype depthType; 7148 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 7149 const PetscInt *localPoints, *neighbors; 7150 const PetscSFNode *remotePoints; 7151 PetscInt *localPointsNew; 7152 PetscSFNode *remotePointsNew; 7153 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 7154 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 7155 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7156 PetscErrorCode ierr; 7157 7158 PetscFunctionBegin; 7159 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 7160 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 7161 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 7162 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth); 7163 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7164 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 7165 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7166 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7167 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7168 cMax = cMax < 0 ? cEnd : cMax; 7169 fMax = fMax < 0 ? fEnd : fMax; 7170 eMax = eMax < 0 ? eEnd : eMax; 7171 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7172 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 7173 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 7174 /* Calculate size of new SF */ 7175 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 7176 if (numRoots < 0) PetscFunctionReturn(0); 7177 for (l = 0; l < numLeaves; ++l) { 7178 const PetscInt p = localPoints[l]; 7179 7180 switch (refiner) { 7181 case REFINER_SIMPLEX_1D: 7182 if ((p >= vStart) && (p < vEnd)) { 7183 /* Interior vertices stay the same */ 7184 ++numLeavesNew; 7185 } else if ((p >= cStart && p < cMax)) { 7186 /* Interior cells add new cells and interior vertices */ 7187 numLeavesNew += 2 + 1; 7188 } 7189 break; 7190 case REFINER_SIMPLEX_2D: 7191 case REFINER_HYBRID_SIMPLEX_2D: 7192 if ((p >= vStart) && (p < vEnd)) { 7193 /* Interior vertices stay the same */ 7194 ++numLeavesNew; 7195 } else if ((p >= fStart) && (p < fMax)) { 7196 /* Interior faces add new faces and vertex */ 7197 numLeavesNew += 2 + 1; 7198 } else if ((p >= fMax) && (p < fEnd)) { 7199 /* Hybrid faces stay the same */ 7200 ++numLeavesNew; 7201 } else if ((p >= cStart) && (p < cMax)) { 7202 /* Interior cells add new cells and interior faces */ 7203 numLeavesNew += 4 + 3; 7204 } else if ((p >= cMax) && (p < cEnd)) { 7205 /* Hybrid cells add new cells and hybrid face */ 7206 numLeavesNew += 2 + 1; 7207 } 7208 break; 7209 case REFINER_SIMPLEX_TO_HEX_2D: 7210 if ((p >= vStart) && (p < vEnd)) { 7211 /* Interior vertices stay the same */ 7212 ++numLeavesNew; 7213 } else if ((p >= fStart) && (p < fEnd)) { 7214 /* Interior faces add new faces and vertex */ 7215 numLeavesNew += 2 + 1; 7216 } else if ((p >= cStart) && (p < cEnd)) { 7217 /* Interior cells add new cells, interior faces, and vertex */ 7218 numLeavesNew += 3 + 3 + 1; 7219 } 7220 break; 7221 case REFINER_HEX_2D: 7222 case REFINER_HYBRID_HEX_2D: 7223 if ((p >= vStart) && (p < vEnd)) { 7224 /* Interior vertices stay the same */ 7225 ++numLeavesNew; 7226 } else if ((p >= fStart) && (p < fMax)) { 7227 /* Interior faces add new faces and vertex */ 7228 numLeavesNew += 2 + 1; 7229 } else if ((p >= fMax) && (p < fEnd)) { 7230 /* Hybrid faces stay the same */ 7231 ++numLeavesNew; 7232 } else if ((p >= cStart) && (p < cMax)) { 7233 /* Interior cells add new cells, interior faces, and vertex */ 7234 numLeavesNew += 4 + 4 + 1; 7235 } else if ((p >= cMax) && (p < cEnd)) { 7236 /* Hybrid cells add new cells and hybrid face */ 7237 numLeavesNew += 2 + 1; 7238 } 7239 break; 7240 case REFINER_SIMPLEX_3D: 7241 case REFINER_HYBRID_SIMPLEX_3D: 7242 if ((p >= vStart) && (p < vEnd)) { 7243 /* Interior vertices stay the same */ 7244 ++numLeavesNew; 7245 } else if ((p >= eStart) && (p < eMax)) { 7246 /* Interior edges add new edges and vertex */ 7247 numLeavesNew += 2 + 1; 7248 } else if ((p >= eMax) && (p < eEnd)) { 7249 /* Hybrid edges stay the same */ 7250 ++numLeavesNew; 7251 } else if ((p >= fStart) && (p < fMax)) { 7252 /* Interior faces add new faces and edges */ 7253 numLeavesNew += 4 + 3; 7254 } else if ((p >= fMax) && (p < fEnd)) { 7255 /* Hybrid faces add new faces and edges */ 7256 numLeavesNew += 2 + 1; 7257 } else if ((p >= cStart) && (p < cMax)) { 7258 /* Interior cells add new cells, faces, and edges */ 7259 numLeavesNew += 8 + 8 + 1; 7260 } else if ((p >= cMax) && (p < cEnd)) { 7261 /* Hybrid cells add new cells and faces */ 7262 numLeavesNew += 4 + 3; 7263 } 7264 break; 7265 case REFINER_SIMPLEX_TO_HEX_3D: 7266 if ((p >= vStart) && (p < vEnd)) { 7267 /* Interior vertices stay the same */ 7268 ++numLeavesNew; 7269 } else if ((p >= eStart) && (p < eEnd)) { 7270 /* Interior edges add new edges and vertex */ 7271 numLeavesNew += 2 + 1; 7272 } else if ((p >= fStart) && (p < fEnd)) { 7273 /* Interior faces add new faces, edges and a vertex */ 7274 numLeavesNew += 3 + 3 + 1; 7275 } else if ((p >= cStart) && (p < cEnd)) { 7276 /* Interior cells add new cells, faces, edges and a vertex */ 7277 numLeavesNew += 4 + 6 + 4 + 1; 7278 } 7279 break; 7280 case REFINER_HEX_3D: 7281 case REFINER_HYBRID_HEX_3D: 7282 if ((p >= vStart) && (p < vEnd)) { 7283 /* Old vertices stay the same */ 7284 ++numLeavesNew; 7285 } else if ((p >= eStart) && (p < eMax)) { 7286 /* Interior edges add new edges, and vertex */ 7287 numLeavesNew += 2 + 1; 7288 } else if ((p >= eMax) && (p < eEnd)) { 7289 /* Hybrid edges stay the same */ 7290 ++numLeavesNew; 7291 } else if ((p >= fStart) && (p < fMax)) { 7292 /* Interior faces add new faces, edges, and vertex */ 7293 numLeavesNew += 4 + 4 + 1; 7294 } else if ((p >= fMax) && (p < fEnd)) { 7295 /* Hybrid faces add new faces and edges */ 7296 numLeavesNew += 2 + 1; 7297 } else if ((p >= cStart) && (p < cMax)) { 7298 /* Interior cells add new cells, faces, edges, and vertex */ 7299 numLeavesNew += 8 + 12 + 6 + 1; 7300 } else if ((p >= cStart) && (p < cEnd)) { 7301 /* Hybrid cells add new cells, faces, and edges */ 7302 numLeavesNew += 4 + 4 + 1; 7303 } 7304 break; 7305 default: 7306 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7307 } 7308 } 7309 /* Communicate depthSizes for each remote rank */ 7310 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 7311 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 7312 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 7313 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 7314 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 7315 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 7316 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 7317 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 7318 for (n = 0; n < numNeighbors; ++n) { 7319 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 7320 } 7321 depthSizeOld[depth] = cMax; 7322 depthSizeOld[0] = vMax; 7323 depthSizeOld[depth-1] = fMax; 7324 depthSizeOld[1] = eMax; 7325 7326 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 7327 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 7328 7329 depthSizeOld[depth] = cEnd - cStart; 7330 depthSizeOld[0] = vEnd - vStart; 7331 depthSizeOld[depth-1] = fEnd - fStart; 7332 depthSizeOld[1] = eEnd - eStart; 7333 7334 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 7335 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 7336 for (n = 0; n < numNeighbors; ++n) { 7337 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 7338 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 7339 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]; 7340 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 7341 } 7342 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 7343 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 7344 /* Calculate new point SF */ 7345 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 7346 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 7347 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 7348 for (l = 0, m = 0; l < numLeaves; ++l) { 7349 PetscInt p = localPoints[l]; 7350 PetscInt rp = remotePoints[l].index, n; 7351 PetscMPIInt rrank = remotePoints[l].rank; 7352 7353 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 7354 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 7355 switch (refiner) { 7356 case REFINER_SIMPLEX_1D: 7357 if ((p >= vStart) && (p < vEnd)) { 7358 /* Old vertices stay the same */ 7359 localPointsNew[m] = vStartNew + (p - vStart); 7360 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7361 remotePointsNew[m].rank = rrank; 7362 ++m; 7363 } else if ((p >= cStart) && (p < cMax)) { 7364 /* Old interior cells add new cells and vertex */ 7365 for (r = 0; r < 2; ++r, ++m) { 7366 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 7367 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 7368 remotePointsNew[m].rank = rrank; 7369 } 7370 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 7371 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 7372 remotePointsNew[m].rank = rrank; 7373 ++m; 7374 } 7375 break; 7376 case REFINER_SIMPLEX_2D: 7377 case REFINER_HYBRID_SIMPLEX_2D: 7378 if ((p >= vStart) && (p < vEnd)) { 7379 /* Old vertices stay the same */ 7380 localPointsNew[m] = vStartNew + (p - vStart); 7381 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7382 remotePointsNew[m].rank = rrank; 7383 ++m; 7384 } else if ((p >= fStart) && (p < fMax)) { 7385 /* Old interior faces add new faces and vertex */ 7386 for (r = 0; r < 2; ++r, ++m) { 7387 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7388 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7389 remotePointsNew[m].rank = rrank; 7390 } 7391 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7392 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7393 remotePointsNew[m].rank = rrank; 7394 ++m; 7395 } else if ((p >= fMax) && (p < fEnd)) { 7396 /* Old hybrid faces stay the same */ 7397 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 7398 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 7399 remotePointsNew[m].rank = rrank; 7400 ++m; 7401 } else if ((p >= cStart) && (p < cMax)) { 7402 /* Old interior cells add new cells and interior faces */ 7403 for (r = 0; r < 4; ++r, ++m) { 7404 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7405 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7406 remotePointsNew[m].rank = rrank; 7407 } 7408 for (r = 0; r < 3; ++r, ++m) { 7409 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 7410 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 7411 remotePointsNew[m].rank = rrank; 7412 } 7413 } else if ((p >= cMax) && (p < cEnd)) { 7414 /* Old hybrid cells add new cells and hybrid face */ 7415 for (r = 0; r < 2; ++r, ++m) { 7416 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7417 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7418 remotePointsNew[m].rank = rrank; 7419 } 7420 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 7421 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]); 7422 remotePointsNew[m].rank = rrank; 7423 ++m; 7424 } 7425 break; 7426 case REFINER_SIMPLEX_TO_HEX_2D: 7427 if ((p >= vStart) && (p < vEnd)) { 7428 /* Old vertices stay the same */ 7429 localPointsNew[m] = vStartNew + (p - vStart); 7430 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7431 remotePointsNew[m].rank = rrank; 7432 ++m; 7433 } else if ((p >= fStart) && (p < fEnd)) { 7434 /* Old interior faces add new faces and vertex */ 7435 for (r = 0; r < 2; ++r, ++m) { 7436 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7437 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7438 remotePointsNew[m].rank = rrank; 7439 } 7440 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7441 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7442 remotePointsNew[m].rank = rrank; 7443 ++m; 7444 } else if ((p >= cStart) && (p < cEnd)) { 7445 /* Old interior cells add new cells, interior faces, and a vertex */ 7446 for (r = 0; r < 3; ++r, ++m) { 7447 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 7448 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 7449 remotePointsNew[m].rank = rrank; 7450 } 7451 for (r = 0; r < 3; ++r, ++m) { 7452 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7453 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 7454 remotePointsNew[m].rank = rrank; 7455 } 7456 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7457 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 7458 remotePointsNew[m].rank = rrank; 7459 ++m; 7460 } 7461 break; 7462 case REFINER_HEX_2D: 7463 case REFINER_HYBRID_HEX_2D: 7464 if ((p >= vStart) && (p < vEnd)) { 7465 /* Old vertices stay the same */ 7466 localPointsNew[m] = vStartNew + (p - vStart); 7467 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7468 remotePointsNew[m].rank = rrank; 7469 ++m; 7470 } else if ((p >= fStart) && (p < fMax)) { 7471 /* Old interior faces add new faces and vertex */ 7472 for (r = 0; r < 2; ++r, ++m) { 7473 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7474 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7475 remotePointsNew[m].rank = rrank; 7476 } 7477 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7478 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7479 remotePointsNew[m].rank = rrank; 7480 ++m; 7481 } else if ((p >= fMax) && (p < fEnd)) { 7482 /* Old hybrid faces stay the same */ 7483 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 7484 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 7485 remotePointsNew[m].rank = rrank; 7486 ++m; 7487 } else if ((p >= cStart) && (p < cMax)) { 7488 /* Old interior cells add new cells, interior faces, and vertex */ 7489 for (r = 0; r < 4; ++r, ++m) { 7490 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7491 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7492 remotePointsNew[m].rank = rrank; 7493 } 7494 for (r = 0; r < 4; ++r, ++m) { 7495 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 7496 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 7497 remotePointsNew[m].rank = rrank; 7498 } 7499 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 7500 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 7501 remotePointsNew[m].rank = rrank; 7502 ++m; 7503 } else if ((p >= cStart) && (p < cMax)) { 7504 /* Old hybrid cells add new cells and hybrid face */ 7505 for (r = 0; r < 2; ++r, ++m) { 7506 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7507 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7508 remotePointsNew[m].rank = rrank; 7509 } 7510 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 7511 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]); 7512 remotePointsNew[m].rank = rrank; 7513 ++m; 7514 } 7515 break; 7516 case REFINER_SIMPLEX_3D: 7517 case REFINER_HYBRID_SIMPLEX_3D: 7518 if ((p >= vStart) && (p < vEnd)) { 7519 /* Interior vertices stay the same */ 7520 localPointsNew[m] = vStartNew + (p - vStart); 7521 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7522 remotePointsNew[m].rank = rrank; 7523 ++m; 7524 } else if ((p >= eStart) && (p < eMax)) { 7525 /* Interior edges add new edges and vertex */ 7526 for (r = 0; r < 2; ++r, ++m) { 7527 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7528 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7529 remotePointsNew[m].rank = rrank; 7530 } 7531 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7532 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7533 remotePointsNew[m].rank = rrank; 7534 ++m; 7535 } else if ((p >= eMax) && (p < eEnd)) { 7536 /* Hybrid edges stay the same */ 7537 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 7538 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]); 7539 remotePointsNew[m].rank = rrank; 7540 ++m; 7541 } else if ((p >= fStart) && (p < fMax)) { 7542 /* Interior faces add new faces and edges */ 7543 for (r = 0; r < 4; ++r, ++m) { 7544 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7545 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7546 remotePointsNew[m].rank = rrank; 7547 } 7548 for (r = 0; r < 3; ++r, ++m) { 7549 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 7550 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 7551 remotePointsNew[m].rank = rrank; 7552 } 7553 } else if ((p >= fMax) && (p < fEnd)) { 7554 /* Hybrid faces add new faces and edges */ 7555 for (r = 0; r < 2; ++r, ++m) { 7556 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 7557 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; 7558 remotePointsNew[m].rank = rrank; 7559 } 7560 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 7561 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]); 7562 remotePointsNew[m].rank = rrank; 7563 ++m; 7564 } else if ((p >= cStart) && (p < cMax)) { 7565 /* Interior cells add new cells, faces, and edges */ 7566 for (r = 0; r < 8; ++r, ++m) { 7567 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7568 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7569 remotePointsNew[m].rank = rrank; 7570 } 7571 for (r = 0; r < 8; ++r, ++m) { 7572 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 7573 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 7574 remotePointsNew[m].rank = rrank; 7575 } 7576 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 7577 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; 7578 remotePointsNew[m].rank = rrank; 7579 ++m; 7580 } else if ((p >= cMax) && (p < cEnd)) { 7581 /* Hybrid cells add new cells and faces */ 7582 for (r = 0; r < 4; ++r, ++m) { 7583 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7584 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7585 remotePointsNew[m].rank = rrank; 7586 } 7587 for (r = 0; r < 3; ++r, ++m) { 7588 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 7589 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; 7590 remotePointsNew[m].rank = rrank; 7591 } 7592 } 7593 break; 7594 case REFINER_SIMPLEX_TO_HEX_3D: 7595 if ((p >= vStart) && (p < vEnd)) { 7596 /* Interior vertices stay the same */ 7597 localPointsNew[m] = vStartNew + (p - vStart); 7598 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7599 remotePointsNew[m].rank = rrank; 7600 ++m; 7601 } else if ((p >= eStart) && (p < eEnd)) { 7602 /* Interior edges add new edges and vertex */ 7603 for (r = 0; r < 2; ++r, ++m) { 7604 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7605 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7606 remotePointsNew[m].rank = rrank; 7607 } 7608 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7609 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7610 remotePointsNew[m].rank = rrank; 7611 ++m; 7612 } else if ((p >= fStart) && (p < fEnd)) { 7613 /* Interior faces add new faces, edges and a vertex */ 7614 for (r = 0; r < 3; ++r, ++m) { 7615 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 7616 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 7617 remotePointsNew[m].rank = rrank; 7618 } 7619 for (r = 0; r < 3; ++r, ++m) { 7620 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 7621 remotePointsNew[m].index = reStartNew[n] + (rdepthSizeOld[n*(depth+1)+1])*2 + (rp - rfStart[n])*3 + r; 7622 remotePointsNew[m].rank = rrank; 7623 } 7624 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 7625 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 7626 remotePointsNew[m].rank = rrank; 7627 ++m; 7628 } else if ((p >= cStart) && (p < cEnd)) { 7629 /* Interior cells add new cells, faces, edges, and a vertex */ 7630 for (r = 0; r < 4; ++r, ++m) { 7631 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7632 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7633 remotePointsNew[m].rank = rrank; 7634 } 7635 for (r = 0; r < 6; ++r, ++m) { 7636 localPointsNew[m] = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 7637 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*6 + r; 7638 remotePointsNew[m].rank = rrank; 7639 } 7640 for (r = 0; r < 4; ++r, ++m) { 7641 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 7642 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*4 + r; 7643 remotePointsNew[m].rank = rrank; 7644 } 7645 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 7646 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 7647 remotePointsNew[m].rank = rrank; 7648 ++m; 7649 } 7650 break; 7651 case REFINER_HEX_3D: 7652 case REFINER_HYBRID_HEX_3D: 7653 if ((p >= vStart) && (p < vEnd)) { 7654 /* Interior vertices stay the same */ 7655 localPointsNew[m] = vStartNew + (p - vStart); 7656 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7657 remotePointsNew[m].rank = rrank; 7658 ++m; 7659 } else if ((p >= eStart) && (p < eMax)) { 7660 /* Interior edges add new edges and vertex */ 7661 for (r = 0; r < 2; ++r, ++m) { 7662 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7663 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7664 remotePointsNew[m].rank = rrank; 7665 } 7666 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7667 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7668 remotePointsNew[m].rank = rrank; 7669 ++m; 7670 } else if ((p >= eMax) && (p < eEnd)) { 7671 /* Hybrid edges stay the same */ 7672 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 7673 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]); 7674 remotePointsNew[m].rank = rrank; 7675 ++m; 7676 } else if ((p >= fStart) && (p < fMax)) { 7677 /* Interior faces add new faces, edges, and vertex */ 7678 for (r = 0; r < 4; ++r, ++m) { 7679 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7680 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7681 remotePointsNew[m].rank = rrank; 7682 } 7683 for (r = 0; r < 4; ++r, ++m) { 7684 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 7685 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 7686 remotePointsNew[m].rank = rrank; 7687 } 7688 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 7689 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 7690 remotePointsNew[m].rank = rrank; 7691 ++m; 7692 } else if ((p >= fMax) && (p < fEnd)) { 7693 /* Hybrid faces add new faces and edges */ 7694 for (r = 0; r < 2; ++r, ++m) { 7695 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 7696 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; 7697 remotePointsNew[m].rank = rrank; 7698 } 7699 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 7700 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]); 7701 remotePointsNew[m].rank = rrank; 7702 ++m; 7703 } else if ((p >= cStart) && (p < cMax)) { 7704 /* Interior cells add new cells, faces, edges, and vertex */ 7705 for (r = 0; r < 8; ++r, ++m) { 7706 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7707 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7708 remotePointsNew[m].rank = rrank; 7709 } 7710 for (r = 0; r < 12; ++r, ++m) { 7711 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 7712 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 7713 remotePointsNew[m].rank = rrank; 7714 } 7715 for (r = 0; r < 6; ++r, ++m) { 7716 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 7717 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; 7718 remotePointsNew[m].rank = rrank; 7719 } 7720 for (r = 0; r < 1; ++r, ++m) { 7721 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 7722 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 7723 remotePointsNew[m].rank = rrank; 7724 } 7725 } else if ((p >= cMax) && (p < cEnd)) { 7726 /* Hybrid cells add new cells, faces, and edges */ 7727 for (r = 0; r < 4; ++r, ++m) { 7728 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7729 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7730 remotePointsNew[m].rank = rrank; 7731 } 7732 for (r = 0; r < 4; ++r, ++m) { 7733 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 7734 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; 7735 remotePointsNew[m].rank = rrank; 7736 } 7737 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 7738 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]); 7739 remotePointsNew[m].rank = rrank; 7740 ++m; 7741 } 7742 break; 7743 default: 7744 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7745 } 7746 } 7747 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 7748 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 7749 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 7750 { 7751 PetscSFNode *rp, *rtmp; 7752 PetscInt *lp, *idx, *ltmp, i; 7753 7754 /* SF needs sorted leaves to correct calculate Gather */ 7755 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 7756 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 7757 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 7758 for (i = 0; i < numLeavesNew; ++i) { 7759 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); 7760 idx[i] = i; 7761 } 7762 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 7763 for (i = 0; i < numLeavesNew; ++i) { 7764 lp[i] = localPointsNew[idx[i]]; 7765 rp[i] = remotePointsNew[idx[i]]; 7766 } 7767 ltmp = localPointsNew; 7768 localPointsNew = lp; 7769 rtmp = remotePointsNew; 7770 remotePointsNew = rp; 7771 ierr = PetscFree(idx);CHKERRQ(ierr); 7772 ierr = PetscFree(ltmp);CHKERRQ(ierr); 7773 ierr = PetscFree(rtmp);CHKERRQ(ierr); 7774 } 7775 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 7776 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 7777 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 7778 PetscFunctionReturn(0); 7779 } 7780 7781 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 7782 { 7783 PetscInt numLabels, l; 7784 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 7785 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7786 PetscErrorCode ierr; 7787 7788 PetscFunctionBegin; 7789 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7790 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 7791 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7792 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7793 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 7794 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7795 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 7796 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7797 switch (refiner) { 7798 case REFINER_NOOP: 7799 case REFINER_SIMPLEX_1D: 7800 case REFINER_SIMPLEX_2D: 7801 case REFINER_SIMPLEX_TO_HEX_2D: 7802 case REFINER_HEX_2D: 7803 case REFINER_SIMPLEX_3D: 7804 case REFINER_HEX_3D: 7805 case REFINER_SIMPLEX_TO_HEX_3D: 7806 break; 7807 case REFINER_HYBRID_SIMPLEX_3D: 7808 case REFINER_HYBRID_HEX_3D: 7809 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 7810 case REFINER_HYBRID_SIMPLEX_2D: 7811 case REFINER_HYBRID_HEX_2D: 7812 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 7813 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 7814 break; 7815 default: 7816 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7817 } 7818 for (l = 0; l < numLabels; ++l) { 7819 DMLabel label, labelNew; 7820 const char *lname; 7821 PetscBool isDepth; 7822 IS valueIS; 7823 const PetscInt *values; 7824 PetscInt defVal; 7825 PetscInt numValues, val; 7826 7827 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 7828 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 7829 if (isDepth) continue; 7830 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 7831 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 7832 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 7833 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 7834 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 7835 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 7836 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 7837 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 7838 for (val = 0; val < numValues; ++val) { 7839 IS pointIS; 7840 const PetscInt *points; 7841 PetscInt numPoints, n; 7842 7843 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 7844 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 7845 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 7846 /* Ensure refined label is created with same number of strata as 7847 * original (even if no entries here). */ 7848 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 7849 for (n = 0; n < numPoints; ++n) { 7850 const PetscInt p = points[n]; 7851 switch (refiner) { 7852 case REFINER_SIMPLEX_1D: 7853 if ((p >= vStart) && (p < vEnd)) { 7854 /* Old vertices stay the same */ 7855 newp = vStartNew + (p - vStart); 7856 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7857 } else if ((p >= cStart) && (p < cEnd)) { 7858 /* Old cells add new cells and vertex */ 7859 newp = vStartNew + (vEnd - vStart) + (p - cStart); 7860 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7861 for (r = 0; r < 2; ++r) { 7862 newp = cStartNew + (p - cStart)*2 + r; 7863 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7864 } 7865 } 7866 break; 7867 case REFINER_SIMPLEX_2D: 7868 if ((p >= vStart) && (p < vEnd)) { 7869 /* Old vertices stay the same */ 7870 newp = vStartNew + (p - vStart); 7871 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7872 } else if ((p >= fStart) && (p < fEnd)) { 7873 /* Old faces add new faces and vertex */ 7874 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7875 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7876 for (r = 0; r < 2; ++r) { 7877 newp = fStartNew + (p - fStart)*2 + r; 7878 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7879 } 7880 } else if ((p >= cStart) && (p < cEnd)) { 7881 /* Old cells add new cells and interior faces */ 7882 for (r = 0; r < 4; ++r) { 7883 newp = cStartNew + (p - cStart)*4 + r; 7884 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7885 } 7886 for (r = 0; r < 3; ++r) { 7887 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7888 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7889 } 7890 } 7891 break; 7892 case REFINER_SIMPLEX_TO_HEX_2D: 7893 if ((p >= vStart) && (p < vEnd)) { 7894 /* Old vertices stay the same */ 7895 newp = vStartNew + (p - vStart); 7896 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7897 } else if ((p >= fStart) && (p < fEnd)) { 7898 /* Old faces add new faces and vertex */ 7899 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7900 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7901 for (r = 0; r < 2; ++r) { 7902 newp = fStartNew + (p - fStart)*2 + r; 7903 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7904 } 7905 } else if ((p >= cStart) && (p < cEnd)) { 7906 /* Old cells add new cells, interior faces, and a vertex */ 7907 for (r = 0; r < 3; ++r) { 7908 newp = cStartNew + (p - cStart)*3 + r; 7909 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7910 } 7911 for (r = 0; r < 3; ++r) { 7912 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7913 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7914 } 7915 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 7916 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7917 } 7918 break; 7919 case REFINER_HEX_2D: 7920 if ((p >= vStart) && (p < vEnd)) { 7921 /* Old vertices stay the same */ 7922 newp = vStartNew + (p - vStart); 7923 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7924 } else if ((p >= fStart) && (p < fEnd)) { 7925 /* Old faces add new faces and vertex */ 7926 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7927 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7928 for (r = 0; r < 2; ++r) { 7929 newp = fStartNew + (p - fStart)*2 + r; 7930 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7931 } 7932 } else if ((p >= cStart) && (p < cEnd)) { 7933 /* Old cells add new cells and interior faces and vertex */ 7934 for (r = 0; r < 4; ++r) { 7935 newp = cStartNew + (p - cStart)*4 + r; 7936 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7937 } 7938 for (r = 0; r < 4; ++r) { 7939 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 7940 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7941 } 7942 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7943 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7944 } 7945 break; 7946 case REFINER_HYBRID_SIMPLEX_2D: 7947 if ((p >= vStart) && (p < vEnd)) { 7948 /* Old vertices stay the same */ 7949 newp = vStartNew + (p - vStart); 7950 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7951 } else if ((p >= fStart) && (p < fMax)) { 7952 /* Old interior faces add new faces and vertex */ 7953 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7954 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7955 for (r = 0; r < 2; ++r) { 7956 newp = fStartNew + (p - fStart)*2 + r; 7957 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7958 } 7959 } else if ((p >= fMax) && (p < fEnd)) { 7960 /* Old hybrid faces stay the same */ 7961 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 7962 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7963 } else if ((p >= cStart) && (p < cMax)) { 7964 /* Old interior cells add new cells and interior faces */ 7965 for (r = 0; r < 4; ++r) { 7966 newp = cStartNew + (p - cStart)*4 + r; 7967 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7968 } 7969 for (r = 0; r < 3; ++r) { 7970 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7971 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7972 } 7973 } else if ((p >= cMax) && (p < cEnd)) { 7974 /* Old hybrid cells add new cells and hybrid face */ 7975 for (r = 0; r < 2; ++r) { 7976 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 7977 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7978 } 7979 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 7980 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7981 } 7982 break; 7983 case REFINER_HYBRID_HEX_2D: 7984 if ((p >= vStart) && (p < vEnd)) { 7985 /* Old vertices stay the same */ 7986 newp = vStartNew + (p - vStart); 7987 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7988 } else if ((p >= fStart) && (p < fMax)) { 7989 /* Old interior faces add new faces and vertex */ 7990 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7991 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7992 for (r = 0; r < 2; ++r) { 7993 newp = fStartNew + (p - fStart)*2 + r; 7994 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7995 } 7996 } else if ((p >= fMax) && (p < fEnd)) { 7997 /* Old hybrid faces stay the same */ 7998 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 7999 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8000 } else if ((p >= cStart) && (p < cMax)) { 8001 /* Old interior cells add new cells, interior faces, and vertex */ 8002 for (r = 0; r < 4; ++r) { 8003 newp = cStartNew + (p - cStart)*4 + r; 8004 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8005 } 8006 for (r = 0; r < 4; ++r) { 8007 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 8008 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8009 } 8010 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 8011 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8012 } else if ((p >= cMax) && (p < cEnd)) { 8013 /* Old hybrid cells add new cells and hybrid face */ 8014 for (r = 0; r < 2; ++r) { 8015 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 8016 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8017 } 8018 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 8019 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8020 } 8021 break; 8022 case REFINER_SIMPLEX_3D: 8023 if ((p >= vStart) && (p < vEnd)) { 8024 /* Old vertices stay the same */ 8025 newp = vStartNew + (p - vStart); 8026 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8027 } else if ((p >= eStart) && (p < eEnd)) { 8028 /* Old edges add new edges and vertex */ 8029 for (r = 0; r < 2; ++r) { 8030 newp = eStartNew + (p - eStart)*2 + r; 8031 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8032 } 8033 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8034 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8035 } else if ((p >= fStart) && (p < fEnd)) { 8036 /* Old faces add new faces and edges */ 8037 for (r = 0; r < 4; ++r) { 8038 newp = fStartNew + (p - fStart)*4 + r; 8039 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8040 } 8041 for (r = 0; r < 3; ++r) { 8042 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 8043 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8044 } 8045 } else if ((p >= cStart) && (p < cEnd)) { 8046 /* Old cells add new cells and interior faces and edges */ 8047 for (r = 0; r < 8; ++r) { 8048 newp = cStartNew + (p - cStart)*8 + r; 8049 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8050 } 8051 for (r = 0; r < 8; ++r) { 8052 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 8053 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8054 } 8055 for (r = 0; r < 1; ++r) { 8056 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 8057 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8058 } 8059 } 8060 break; 8061 case REFINER_SIMPLEX_TO_HEX_3D: 8062 if ((p >= vStart) && (p < vEnd)) { 8063 /* Old vertices stay the same */ 8064 newp = vStartNew + (p - vStart); 8065 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8066 } else if ((p >= eStart) && (p < eEnd)) { 8067 /* Old edges add new edges and vertex */ 8068 for (r = 0; r < 2; ++r) { 8069 newp = eStartNew + (p - eStart)*2 + r; 8070 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8071 } 8072 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8073 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8074 } else if ((p >= fStart) && (p < fEnd)) { 8075 /* Old faces add new faces, edges and a vertex */ 8076 for (r = 0; r < 3; ++r) { 8077 newp = fStartNew + (p - fStart)*3 + r; 8078 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8079 } 8080 for (r = 0; r < 3; ++r) { 8081 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 8082 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8083 } 8084 } else if ((p >= cStart) && (p < cEnd)) { 8085 /* Old cells add new cells and interior faces and edges and a vertex */ 8086 for (r = 0; r < 4; ++r) { 8087 newp = cStartNew + (p - cStart)*4 + r; 8088 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8089 } 8090 for (r = 0; r < 6; ++r) { 8091 newp = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 8092 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8093 } 8094 for (r = 0; r < 4; ++r) { 8095 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 8096 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8097 } 8098 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + p - cStart; 8099 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8100 } 8101 break; 8102 case REFINER_HYBRID_SIMPLEX_3D: 8103 if ((p >= vStart) && (p < vEnd)) { 8104 /* Interior vertices stay the same */ 8105 newp = vStartNew + (p - vStart); 8106 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8107 } else if ((p >= eStart) && (p < eMax)) { 8108 /* Interior edges add new edges and vertex */ 8109 for (r = 0; r < 2; ++r) { 8110 newp = eStartNew + (p - eStart)*2 + r; 8111 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8112 } 8113 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8114 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8115 } else if ((p >= eMax) && (p < eEnd)) { 8116 /* Hybrid edges stay the same */ 8117 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 8118 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8119 } else if ((p >= fStart) && (p < fMax)) { 8120 /* Interior faces add new faces and edges */ 8121 for (r = 0; r < 4; ++r) { 8122 newp = fStartNew + (p - fStart)*4 + r; 8123 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8124 } 8125 for (r = 0; r < 3; ++r) { 8126 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 8127 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8128 } 8129 } else if ((p >= fMax) && (p < fEnd)) { 8130 /* Hybrid faces add new faces and edges */ 8131 for (r = 0; r < 2; ++r) { 8132 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 8133 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8134 } 8135 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 8136 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8137 } else if ((p >= cStart) && (p < cMax)) { 8138 /* Interior cells add new cells, faces, and edges */ 8139 for (r = 0; r < 8; ++r) { 8140 newp = cStartNew + (p - cStart)*8 + r; 8141 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8142 } 8143 for (r = 0; r < 8; ++r) { 8144 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 8145 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8146 } 8147 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 8148 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8149 } else if ((p >= cMax) && (p < cEnd)) { 8150 /* Hybrid cells add new cells and faces */ 8151 for (r = 0; r < 4; ++r) { 8152 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 8153 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8154 } 8155 for (r = 0; r < 3; ++r) { 8156 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 8157 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8158 } 8159 } 8160 break; 8161 case REFINER_HEX_3D: 8162 if ((p >= vStart) && (p < vEnd)) { 8163 /* Old vertices stay the same */ 8164 newp = vStartNew + (p - vStart); 8165 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8166 } else if ((p >= eStart) && (p < eEnd)) { 8167 /* Old edges add new edges and vertex */ 8168 for (r = 0; r < 2; ++r) { 8169 newp = eStartNew + (p - eStart)*2 + r; 8170 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8171 } 8172 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8173 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8174 } else if ((p >= fStart) && (p < fEnd)) { 8175 /* Old faces add new faces, edges, and vertex */ 8176 for (r = 0; r < 4; ++r) { 8177 newp = fStartNew + (p - fStart)*4 + r; 8178 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8179 } 8180 for (r = 0; r < 4; ++r) { 8181 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 8182 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8183 } 8184 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 8185 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8186 } else if ((p >= cStart) && (p < cEnd)) { 8187 /* Old cells add new cells, faces, edges, and vertex */ 8188 for (r = 0; r < 8; ++r) { 8189 newp = cStartNew + (p - cStart)*8 + r; 8190 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8191 } 8192 for (r = 0; r < 12; ++r) { 8193 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 8194 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8195 } 8196 for (r = 0; r < 6; ++r) { 8197 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 8198 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8199 } 8200 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 8201 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8202 } 8203 break; 8204 case REFINER_HYBRID_HEX_3D: 8205 if ((p >= vStart) && (p < vEnd)) { 8206 /* Interior vertices stay the same */ 8207 newp = vStartNew + (p - vStart); 8208 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8209 } else if ((p >= eStart) && (p < eMax)) { 8210 /* Interior edges add new edges and vertex */ 8211 for (r = 0; r < 2; ++r) { 8212 newp = eStartNew + (p - eStart)*2 + r; 8213 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8214 } 8215 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8216 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8217 } else if ((p >= eMax) && (p < eEnd)) { 8218 /* Hybrid edges stay the same */ 8219 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 8220 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8221 } else if ((p >= fStart) && (p < fMax)) { 8222 /* Interior faces add new faces, edges, and vertex */ 8223 for (r = 0; r < 4; ++r) { 8224 newp = fStartNew + (p - fStart)*4 + r; 8225 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8226 } 8227 for (r = 0; r < 4; ++r) { 8228 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 8229 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8230 } 8231 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 8232 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8233 } else if ((p >= fMax) && (p < fEnd)) { 8234 /* Hybrid faces add new faces and edges */ 8235 for (r = 0; r < 2; ++r) { 8236 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 8237 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8238 } 8239 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 8240 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8241 } else if ((p >= cStart) && (p < cMax)) { 8242 /* Interior cells add new cells, faces, edges, and vertex */ 8243 for (r = 0; r < 8; ++r) { 8244 newp = cStartNew + (p - cStart)*8 + r; 8245 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8246 } 8247 for (r = 0; r < 12; ++r) { 8248 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 8249 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8250 } 8251 for (r = 0; r < 6; ++r) { 8252 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 8253 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8254 } 8255 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 8256 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8257 } else if ((p >= cMax) && (p < cEnd)) { 8258 /* Hybrid cells add new cells, faces, and edges */ 8259 for (r = 0; r < 4; ++r) { 8260 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 8261 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8262 } 8263 for (r = 0; r < 4; ++r) { 8264 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 8265 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8266 } 8267 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 8268 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8269 } 8270 break; 8271 default: 8272 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 8273 } 8274 } 8275 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 8276 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 8277 } 8278 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 8279 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 8280 if (0) { 8281 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 8282 } 8283 } 8284 PetscFunctionReturn(0); 8285 } 8286 8287 /* This will only work for interpolated meshes */ 8288 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 8289 { 8290 DM rdm; 8291 PetscInt *depthSize; 8292 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 8293 PetscErrorCode ierr; 8294 8295 PetscFunctionBegin; 8296 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 8297 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 8298 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8299 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 8300 /* Calculate number of new points of each depth */ 8301 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8302 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 8303 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 8304 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 8305 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 8306 /* Step 1: Set chart */ 8307 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 8308 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 8309 /* Step 2: Set cone/support sizes */ 8310 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8311 /* Step 3: Setup refined DM */ 8312 ierr = DMSetUp(rdm);CHKERRQ(ierr); 8313 /* Step 4: Set cones and supports */ 8314 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8315 /* Step 5: Stratify */ 8316 ierr = DMPlexStratify(rdm);CHKERRQ(ierr); 8317 /* Step 6: Create pointSF */ 8318 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8319 /* Step 7: Create labels */ 8320 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8321 /* Step 8: Set coordinates */ 8322 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8323 ierr = PetscFree(depthSize);CHKERRQ(ierr); 8324 8325 *dmRefined = rdm; 8326 PetscFunctionReturn(0); 8327 } 8328 8329 /*@ 8330 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 8331 8332 Input Parameter: 8333 . dm - The coarse DM 8334 8335 Output Parameter: 8336 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 8337 8338 Level: developer 8339 8340 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 8341 @*/ 8342 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 8343 { 8344 CellRefiner cellRefiner; 8345 PetscInt *depthSize, *fpoints; 8346 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8347 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 8348 PetscErrorCode ierr; 8349 8350 PetscFunctionBegin; 8351 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8352 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 8353 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8354 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 8355 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 8356 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 8357 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8358 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 8359 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 8360 switch (cellRefiner) { 8361 case REFINER_SIMPLEX_1D: 8362 case REFINER_SIMPLEX_2D: 8363 case REFINER_HYBRID_SIMPLEX_2D: 8364 case REFINER_HEX_2D: 8365 case REFINER_HYBRID_HEX_2D: 8366 case REFINER_SIMPLEX_3D: 8367 case REFINER_HYBRID_SIMPLEX_3D: 8368 case REFINER_HEX_3D: 8369 case REFINER_HYBRID_HEX_3D: 8370 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 8371 break; 8372 default: 8373 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 8374 } 8375 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 8376 ierr = PetscFree(depthSize);CHKERRQ(ierr); 8377 PetscFunctionReturn(0); 8378 } 8379 8380 /*@ 8381 DMPlexSetRefinementUniform - Set the flag for uniform refinement 8382 8383 Input Parameters: 8384 + dm - The DM 8385 - refinementUniform - The flag for uniform refinement 8386 8387 Level: developer 8388 8389 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8390 @*/ 8391 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 8392 { 8393 DM_Plex *mesh = (DM_Plex*) dm->data; 8394 8395 PetscFunctionBegin; 8396 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8397 mesh->refinementUniform = refinementUniform; 8398 PetscFunctionReturn(0); 8399 } 8400 8401 /*@ 8402 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 8403 8404 Input Parameter: 8405 . dm - The DM 8406 8407 Output Parameter: 8408 . refinementUniform - The flag for uniform refinement 8409 8410 Level: developer 8411 8412 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8413 @*/ 8414 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 8415 { 8416 DM_Plex *mesh = (DM_Plex*) dm->data; 8417 8418 PetscFunctionBegin; 8419 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8420 PetscValidPointer(refinementUniform, 2); 8421 *refinementUniform = mesh->refinementUniform; 8422 PetscFunctionReturn(0); 8423 } 8424 8425 /*@ 8426 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 8427 8428 Input Parameters: 8429 + dm - The DM 8430 - refinementLimit - The maximum cell volume in the refined mesh 8431 8432 Level: developer 8433 8434 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 8435 @*/ 8436 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 8437 { 8438 DM_Plex *mesh = (DM_Plex*) dm->data; 8439 8440 PetscFunctionBegin; 8441 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8442 mesh->refinementLimit = refinementLimit; 8443 PetscFunctionReturn(0); 8444 } 8445 8446 /*@ 8447 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 8448 8449 Input Parameter: 8450 . dm - The DM 8451 8452 Output Parameter: 8453 . refinementLimit - The maximum cell volume in the refined mesh 8454 8455 Level: developer 8456 8457 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 8458 @*/ 8459 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 8460 { 8461 DM_Plex *mesh = (DM_Plex*) dm->data; 8462 8463 PetscFunctionBegin; 8464 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8465 PetscValidPointer(refinementLimit, 2); 8466 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 8467 *refinementLimit = mesh->refinementLimit; 8468 PetscFunctionReturn(0); 8469 } 8470 8471 /*@ 8472 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 8473 8474 Input Parameters: 8475 + dm - The DM 8476 - refinementFunc - Function giving the maximum cell volume in the refined mesh 8477 8478 Note: The calling sequence is refinementFunc(coords, limit) 8479 $ coords - Coordinates of the current point, usually a cell centroid 8480 $ limit - The maximum cell volume for a cell containing this point 8481 8482 Level: developer 8483 8484 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8485 @*/ 8486 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 8487 { 8488 DM_Plex *mesh = (DM_Plex*) dm->data; 8489 8490 PetscFunctionBegin; 8491 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8492 mesh->refinementFunc = refinementFunc; 8493 PetscFunctionReturn(0); 8494 } 8495 8496 /*@ 8497 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 8498 8499 Input Parameter: 8500 . dm - The DM 8501 8502 Output Parameter: 8503 . refinementFunc - Function giving the maximum cell volume in the refined mesh 8504 8505 Note: The calling sequence is refinementFunc(coords, limit) 8506 $ coords - Coordinates of the current point, usually a cell centroid 8507 $ limit - The maximum cell volume for a cell containing this point 8508 8509 Level: developer 8510 8511 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8512 @*/ 8513 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 8514 { 8515 DM_Plex *mesh = (DM_Plex*) dm->data; 8516 8517 PetscFunctionBegin; 8518 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8519 PetscValidPointer(refinementFunc, 2); 8520 *refinementFunc = mesh->refinementFunc; 8521 PetscFunctionReturn(0); 8522 } 8523 8524 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 8525 { 8526 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 8527 PetscErrorCode ierr; 8528 8529 PetscFunctionBegin; 8530 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8531 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8532 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 8533 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 8534 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 8535 switch (dim) { 8536 case 1: 8537 switch (coneSize) { 8538 case 2: 8539 *cellRefiner = REFINER_SIMPLEX_1D; 8540 break; 8541 default: 8542 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8543 } 8544 break; 8545 case 2: 8546 switch (coneSize) { 8547 case 3: 8548 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 8549 else *cellRefiner = REFINER_SIMPLEX_2D; 8550 break; 8551 case 4: 8552 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 8553 else *cellRefiner = REFINER_HEX_2D; 8554 break; 8555 default: 8556 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8557 } 8558 break; 8559 case 3: 8560 switch (coneSize) { 8561 case 4: 8562 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 8563 else *cellRefiner = REFINER_SIMPLEX_3D; 8564 break; 8565 case 6: 8566 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 8567 else *cellRefiner = REFINER_HEX_3D; 8568 break; 8569 default: 8570 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8571 } 8572 break; 8573 default: 8574 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 8575 } 8576 PetscFunctionReturn(0); 8577 } 8578 8579 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 8580 { 8581 PetscBool isUniform; 8582 PetscErrorCode ierr; 8583 8584 PetscFunctionBegin; 8585 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 8586 if (isUniform) { 8587 CellRefiner cellRefiner; 8588 PetscBool localized; 8589 8590 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 8591 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 8592 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 8593 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 8594 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 8595 } else { 8596 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 8597 } 8598 PetscFunctionReturn(0); 8599 } 8600 8601 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 8602 { 8603 DM cdm = dm; 8604 PetscInt r; 8605 PetscBool isUniform, localized; 8606 PetscErrorCode ierr; 8607 8608 PetscFunctionBegin; 8609 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 8610 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 8611 if (isUniform) { 8612 for (r = 0; r < nlevels; ++r) { 8613 CellRefiner cellRefiner; 8614 8615 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 8616 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 8617 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 8618 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 8619 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 8620 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 8621 cdm = dmRefined[r]; 8622 } 8623 } else { 8624 for (r = 0; r < nlevels; ++r) { 8625 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 8626 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 8627 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 8628 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 8629 cdm = dmRefined[r]; 8630 } 8631 } 8632 PetscFunctionReturn(0); 8633 } 8634