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 DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd) 376 { 377 IS cIS; 378 PetscErrorCode ierr; 379 380 PetscFunctionBegin; 381 ierr = ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);CHKERRQ(ierr); 382 ierr = DMLabelSetStratumIS(label, value, cIS);CHKERRQ(ierr); 383 ierr = ISDestroy(&cIS);CHKERRQ(ierr); 384 PetscFunctionReturn(0); 385 } 386 387 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 388 { 389 PetscInt depth, cStart, cStartNew, cEnd, cEndNew, cMax, c, vStart, vStartNew, vEnd, vEndNew, vMax, v, fStart, fStartNew, fEnd, fEndNew, fMax, f, eStart, eStartNew, eEnd, eEndNew, eMax, e, r; 390 DMLabel depthLabel; 391 PetscErrorCode ierr; 392 393 PetscFunctionBegin; 394 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 395 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 396 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 397 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 398 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 399 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 400 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 401 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 402 ierr = DMCreateLabel(rdm,"depth");CHKERRQ(ierr); 403 ierr = DMPlexGetDepthLabel(rdm,&depthLabel);CHKERRQ(ierr); 404 ierr = DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);CHKERRQ(ierr); 405 if (depth > 2) ierr = DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);CHKERRQ(ierr); 406 if (depth > 1) ierr = DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);CHKERRQ(ierr); 407 if (depth > 0) ierr = DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);CHKERRQ(ierr); 408 { 409 DM_Plex *plex = (DM_Plex *) rdm->data; 410 ierr = DMLabelGetState(depthLabel, &plex->depthState);CHKERRQ(ierr); 411 } 412 if (!refiner) PetscFunctionReturn(0); 413 switch (refiner) { 414 case REFINER_SIMPLEX_1D: 415 /* All cells have 2 vertices */ 416 for (c = cStart; c < cEnd; ++c) { 417 for (r = 0; r < 2; ++r) { 418 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 419 420 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 421 } 422 } 423 /* Old vertices have identical supports */ 424 for (v = vStart; v < vEnd; ++v) { 425 const PetscInt newp = vStartNew + (v - vStart); 426 PetscInt size; 427 428 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 429 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 430 } 431 /* Cell vertices have support 2 */ 432 for (c = cStart; c < cEnd; ++c) { 433 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 434 435 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 436 } 437 break; 438 case REFINER_SIMPLEX_2D: 439 /* All cells have 3 faces */ 440 for (c = cStart; c < cEnd; ++c) { 441 for (r = 0; r < 4; ++r) { 442 const PetscInt newp = (c - cStart)*4 + r; 443 444 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 445 } 446 } 447 /* Split faces have 2 vertices and the same cells as the parent */ 448 for (f = fStart; f < fEnd; ++f) { 449 for (r = 0; r < 2; ++r) { 450 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 451 PetscInt size; 452 453 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 454 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 455 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 456 } 457 } 458 /* Interior faces have 2 vertices and 2 cells */ 459 for (c = cStart; c < cEnd; ++c) { 460 for (r = 0; r < 3; ++r) { 461 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 462 463 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 464 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 465 } 466 } 467 /* Old vertices have identical supports */ 468 for (v = vStart; v < vEnd; ++v) { 469 const PetscInt newp = vStartNew + (v - vStart); 470 PetscInt size; 471 472 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 473 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 474 } 475 /* Face vertices have 2 + cells*2 supports */ 476 for (f = fStart; f < fEnd; ++f) { 477 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 478 PetscInt size; 479 480 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 481 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 482 } 483 break; 484 case REFINER_SIMPLEX_TO_HEX_2D: 485 /* All cells have 4 faces */ 486 for (c = cStart; c < cEnd; ++c) { 487 for (r = 0; r < 3; ++r) { 488 const PetscInt newp = (c - cStart)*3 + r; 489 490 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 491 } 492 } 493 /* Split faces have 2 vertices and the same cells as the parent */ 494 for (f = fStart; f < fEnd; ++f) { 495 for (r = 0; r < 2; ++r) { 496 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 497 PetscInt size; 498 499 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 500 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 501 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 502 } 503 } 504 /* Interior faces have 2 vertices and 2 cells */ 505 for (c = cStart; c < cEnd; ++c) { 506 for (r = 0; r < 3; ++r) { 507 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 508 509 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 510 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 511 } 512 } 513 /* Old vertices have identical supports */ 514 for (v = vStart; v < vEnd; ++v) { 515 const PetscInt newp = vStartNew + (v - vStart); 516 PetscInt size; 517 518 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 519 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 520 } 521 /* Split-face vertices have cells + 2 supports */ 522 for (f = fStart; f < fEnd; ++f) { 523 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 524 PetscInt size; 525 526 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 527 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 528 } 529 /* Interior vertices have 3 supports */ 530 for (c = cStart; c < cEnd; ++c) { 531 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 532 533 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 534 } 535 break; 536 case REFINER_HEX_2D: 537 /* All cells have 4 faces */ 538 for (c = cStart; c < cEnd; ++c) { 539 for (r = 0; r < 4; ++r) { 540 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 541 542 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 543 } 544 } 545 /* Split faces have 2 vertices and the same cells as the parent */ 546 for (f = fStart; f < fEnd; ++f) { 547 for (r = 0; r < 2; ++r) { 548 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 549 PetscInt size; 550 551 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 552 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 553 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 554 } 555 } 556 /* Interior faces have 2 vertices and 2 cells */ 557 for (c = cStart; c < cEnd; ++c) { 558 for (r = 0; r < 4; ++r) { 559 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 560 561 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 562 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 563 } 564 } 565 /* Old vertices have identical supports */ 566 for (v = vStart; v < vEnd; ++v) { 567 const PetscInt newp = vStartNew + (v - vStart); 568 PetscInt size; 569 570 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 571 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 572 } 573 /* Face vertices have 2 + cells supports */ 574 for (f = fStart; f < fEnd; ++f) { 575 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 576 PetscInt size; 577 578 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 579 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 580 } 581 /* Cell vertices have 4 supports */ 582 for (c = cStart; c < cEnd; ++c) { 583 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 584 585 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 586 } 587 break; 588 case REFINER_HYBRID_SIMPLEX_2D: 589 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 590 cMax = PetscMin(cEnd, cMax); 591 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 592 fMax = PetscMin(fEnd, fMax); 593 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 594 /* Interior cells have 3 faces */ 595 for (c = cStart; c < cMax; ++c) { 596 for (r = 0; r < 4; ++r) { 597 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 598 599 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 600 } 601 } 602 /* Hybrid cells have 4 faces */ 603 for (c = cMax; c < cEnd; ++c) { 604 for (r = 0; r < 2; ++r) { 605 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 606 607 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 608 } 609 } 610 /* Interior split faces have 2 vertices and the same cells as the parent */ 611 for (f = fStart; f < fMax; ++f) { 612 for (r = 0; r < 2; ++r) { 613 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 614 PetscInt size; 615 616 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 617 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 618 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 619 } 620 } 621 /* Interior cell faces have 2 vertices and 2 cells */ 622 for (c = cStart; c < cMax; ++c) { 623 for (r = 0; r < 3; ++r) { 624 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 625 626 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 627 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 628 } 629 } 630 /* Hybrid faces have 2 vertices and the same cells */ 631 for (f = fMax; f < fEnd; ++f) { 632 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 633 PetscInt size; 634 635 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 636 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 637 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 638 } 639 /* Hybrid cell faces have 2 vertices and 2 cells */ 640 for (c = cMax; c < cEnd; ++c) { 641 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 642 643 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 644 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 645 } 646 /* Old vertices have identical supports */ 647 for (v = vStart; v < vEnd; ++v) { 648 const PetscInt newp = vStartNew + (v - vStart); 649 PetscInt size; 650 651 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 652 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 653 } 654 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 655 for (f = fStart; f < fMax; ++f) { 656 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 657 const PetscInt *support; 658 PetscInt size, newSize = 2, s; 659 660 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 661 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 662 for (s = 0; s < size; ++s) { 663 if (support[s] >= cMax) newSize += 1; 664 else newSize += 2; 665 } 666 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 667 } 668 break; 669 case REFINER_HYBRID_HEX_2D: 670 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 671 cMax = PetscMin(cEnd, cMax); 672 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 673 fMax = PetscMin(fEnd, fMax); 674 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 675 /* Interior cells have 4 faces */ 676 for (c = cStart; c < cMax; ++c) { 677 for (r = 0; r < 4; ++r) { 678 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 679 680 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 681 } 682 } 683 /* Hybrid cells have 4 faces */ 684 for (c = cMax; c < cEnd; ++c) { 685 for (r = 0; r < 2; ++r) { 686 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 687 688 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 689 } 690 } 691 /* Interior split faces have 2 vertices and the same cells as the parent */ 692 for (f = fStart; f < fMax; ++f) { 693 for (r = 0; r < 2; ++r) { 694 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 695 PetscInt size; 696 697 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 698 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 699 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 700 } 701 } 702 /* Interior cell faces have 2 vertices and 2 cells */ 703 for (c = cStart; c < cMax; ++c) { 704 for (r = 0; r < 4; ++r) { 705 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 706 707 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 708 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 709 } 710 } 711 /* Hybrid faces have 2 vertices and the same cells */ 712 for (f = fMax; f < fEnd; ++f) { 713 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 714 PetscInt size; 715 716 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 717 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 718 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 719 } 720 /* Hybrid cell faces have 2 vertices and 2 cells */ 721 for (c = cMax; c < cEnd; ++c) { 722 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 723 724 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 725 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 726 } 727 /* Old vertices have identical supports */ 728 for (v = vStart; v < vEnd; ++v) { 729 const PetscInt newp = vStartNew + (v - vStart); 730 PetscInt size; 731 732 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 733 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 734 } 735 /* Face vertices have 2 + cells supports */ 736 for (f = fStart; f < fMax; ++f) { 737 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 738 PetscInt size; 739 740 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 741 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 742 } 743 /* Cell vertices have 4 supports */ 744 for (c = cStart; c < cMax; ++c) { 745 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 746 747 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 748 } 749 break; 750 case REFINER_SIMPLEX_3D: 751 /* All cells have 4 faces */ 752 for (c = cStart; c < cEnd; ++c) { 753 for (r = 0; r < 8; ++r) { 754 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 755 756 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 757 } 758 } 759 /* Split faces have 3 edges and the same cells as the parent */ 760 for (f = fStart; f < fEnd; ++f) { 761 for (r = 0; r < 4; ++r) { 762 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 763 PetscInt size; 764 765 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 766 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 767 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 768 } 769 } 770 /* Interior cell faces have 3 edges and 2 cells */ 771 for (c = cStart; c < cEnd; ++c) { 772 for (r = 0; r < 8; ++r) { 773 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 774 775 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 776 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 777 } 778 } 779 /* Split edges have 2 vertices and the same faces */ 780 for (e = eStart; e < eEnd; ++e) { 781 for (r = 0; r < 2; ++r) { 782 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 783 PetscInt size; 784 785 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 786 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 787 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 788 } 789 } 790 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 791 for (f = fStart; f < fEnd; ++f) { 792 for (r = 0; r < 3; ++r) { 793 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 794 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 795 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 796 797 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 798 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 799 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 800 for (s = 0; s < supportSize; ++s) { 801 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 802 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 803 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 804 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 805 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 806 er = GetTriMidEdgeInverse_Static(ornt[c], r); 807 if (er == eint[c]) { 808 intFaces += 1; 809 } else { 810 intFaces += 2; 811 } 812 } 813 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 814 } 815 } 816 /* Interior cell edges have 2 vertices and 4 faces */ 817 for (c = cStart; c < cEnd; ++c) { 818 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 819 820 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 821 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 822 } 823 /* Old vertices have identical supports */ 824 for (v = vStart; v < vEnd; ++v) { 825 const PetscInt newp = vStartNew + (v - vStart); 826 PetscInt size; 827 828 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 829 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 830 } 831 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 832 for (e = eStart; e < eEnd; ++e) { 833 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 834 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 835 836 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 837 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 838 for (s = 0; s < starSize*2; s += 2) { 839 const PetscInt *cone, *ornt; 840 PetscInt e01, e23; 841 842 if ((star[s] >= cStart) && (star[s] < cEnd)) { 843 /* Check edge 0-1 */ 844 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 845 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 846 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 847 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 848 /* Check edge 2-3 */ 849 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 850 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 851 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 852 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 853 if ((e01 == e) || (e23 == e)) ++cellSize; 854 } 855 } 856 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 857 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 858 } 859 break; 860 case REFINER_HYBRID_SIMPLEX_3D: 861 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 862 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 863 /* Interior cells have 4 faces */ 864 for (c = cStart; c < cMax; ++c) { 865 for (r = 0; r < 8; ++r) { 866 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 867 868 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 869 } 870 } 871 /* Hybrid cells have 5 faces */ 872 for (c = cMax; c < cEnd; ++c) { 873 for (r = 0; r < 4; ++r) { 874 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 875 876 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 877 } 878 } 879 /* Interior split faces have 3 edges and the same cells as the parent */ 880 for (f = fStart; f < fMax; ++f) { 881 for (r = 0; r < 4; ++r) { 882 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 883 PetscInt size; 884 885 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 886 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 887 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 888 } 889 } 890 /* Interior cell faces have 3 edges and 2 cells */ 891 for (c = cStart; c < cMax; ++c) { 892 for (r = 0; r < 8; ++r) { 893 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 894 895 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 896 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 897 } 898 } 899 /* Hybrid split faces have 4 edges and the same cells as the parent */ 900 for (f = fMax; f < fEnd; ++f) { 901 for (r = 0; r < 2; ++r) { 902 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 903 PetscInt size; 904 905 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 906 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 907 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 908 } 909 } 910 /* Hybrid cells faces have 4 edges and 2 cells */ 911 for (c = cMax; c < cEnd; ++c) { 912 for (r = 0; r < 3; ++r) { 913 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 914 915 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 916 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 917 } 918 } 919 /* Interior split edges have 2 vertices and the same faces */ 920 for (e = eStart; e < eMax; ++e) { 921 for (r = 0; r < 2; ++r) { 922 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 923 PetscInt size; 924 925 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 926 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 927 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 928 } 929 } 930 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 931 for (f = fStart; f < fMax; ++f) { 932 for (r = 0; r < 3; ++r) { 933 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 934 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 935 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 936 937 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 938 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 939 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 940 for (s = 0; s < supportSize; ++s) { 941 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 942 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 943 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 944 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 945 if (support[s] < cMax) { 946 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 947 er = GetTriMidEdgeInverse_Static(ornt[c], r); 948 if (er == eint[c]) { 949 intFaces += 1; 950 } else { 951 intFaces += 2; 952 } 953 } else { 954 intFaces += 1; 955 } 956 } 957 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 958 } 959 } 960 /* Interior cell edges have 2 vertices and 4 faces */ 961 for (c = cStart; c < cMax; ++c) { 962 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 963 964 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 965 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 966 } 967 /* Hybrid edges have 2 vertices and the same faces */ 968 for (e = eMax; e < eEnd; ++e) { 969 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 970 PetscInt size; 971 972 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 973 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 974 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 975 } 976 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 977 for (f = fMax; f < fEnd; ++f) { 978 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 979 PetscInt size; 980 981 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 982 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 983 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 984 } 985 /* Interior vertices have identical supports */ 986 for (v = vStart; v < vEnd; ++v) { 987 const PetscInt newp = vStartNew + (v - vStart); 988 PetscInt size; 989 990 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 991 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 992 } 993 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 994 for (e = eStart; e < eMax; ++e) { 995 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 996 const PetscInt *support; 997 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 998 999 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1000 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1001 for (s = 0; s < size; ++s) { 1002 if (support[s] < fMax) faceSize += 2; 1003 else faceSize += 1; 1004 } 1005 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1006 for (s = 0; s < starSize*2; s += 2) { 1007 const PetscInt *cone, *ornt; 1008 PetscInt e01, e23; 1009 1010 if ((star[s] >= cStart) && (star[s] < cMax)) { 1011 /* Check edge 0-1 */ 1012 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1013 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1014 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1015 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1016 /* Check edge 2-3 */ 1017 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1018 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1019 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1020 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1021 if ((e01 == e) || (e23 == e)) ++cellSize; 1022 } 1023 } 1024 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1025 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 1026 } 1027 break; 1028 case REFINER_SIMPLEX_TO_HEX_3D: 1029 /* All cells have 6 faces */ 1030 for (c = cStart; c < cEnd; ++c) { 1031 for (r = 0; r < 4; ++r) { 1032 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1033 1034 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1035 } 1036 } 1037 /* Split faces have 4 edges and the same cells as the parent */ 1038 for (f = fStart; f < fEnd; ++f) { 1039 for (r = 0; r < 3; ++r) { 1040 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1041 PetscInt size; 1042 1043 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1044 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1045 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1046 } 1047 } 1048 /* Interior cell faces have 4 edges and 2 cells */ 1049 for (c = cStart; c < cEnd; ++c) { 1050 for (r = 0; r < 6; ++r) { 1051 const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r; 1052 1053 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1054 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1055 } 1056 } 1057 /* Split edges have 2 vertices and the same faces */ 1058 for (e = eStart; e < eEnd; ++e) { 1059 for (r = 0; r < 2; ++r) { 1060 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1061 PetscInt size; 1062 1063 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1064 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1065 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1066 } 1067 } 1068 /* Face edges have 2 vertices and 2 + cell faces supports */ 1069 for (f = fStart; f < fEnd; ++f) { 1070 for (r = 0; r < 3; ++r) { 1071 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1072 PetscInt size; 1073 1074 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1075 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1076 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1077 } 1078 } 1079 /* Interior cell edges have 2 vertices and 3 faces */ 1080 for (c = cStart; c < cEnd; ++c) { 1081 for (r = 0; r < 4; ++r) { 1082 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 1083 1084 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1085 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1086 } 1087 } 1088 /* Old vertices have identical supports */ 1089 for (v = vStart; v < vEnd; ++v) { 1090 const PetscInt newp = vStartNew + (v - vStart); 1091 PetscInt size; 1092 1093 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1094 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1095 } 1096 /* Edge vertices have 2 + faces supports */ 1097 for (e = eStart; e < eEnd; ++e) { 1098 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1099 PetscInt size; 1100 1101 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1102 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1103 } 1104 /* Face vertices have 3 + cells supports */ 1105 for (f = fStart; f < fEnd; ++f) { 1106 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 1107 PetscInt size; 1108 1109 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1110 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1111 } 1112 /* Interior cell vertices have 4 supports */ 1113 for (c = cStart; c < cEnd; ++c) { 1114 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart; 1115 1116 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1117 } 1118 break; 1119 case REFINER_HEX_3D: 1120 /* All cells have 6 faces */ 1121 for (c = cStart; c < cEnd; ++c) { 1122 for (r = 0; r < 8; ++r) { 1123 const PetscInt newp = (c - cStart)*8 + r; 1124 1125 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1126 } 1127 } 1128 /* Split faces have 4 edges and the same cells as the parent */ 1129 for (f = fStart; f < fEnd; ++f) { 1130 for (r = 0; r < 4; ++r) { 1131 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1132 PetscInt size; 1133 1134 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1135 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1136 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1137 } 1138 } 1139 /* Interior faces have 4 edges and 2 cells */ 1140 for (c = cStart; c < cEnd; ++c) { 1141 for (r = 0; r < 12; ++r) { 1142 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 1143 1144 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1145 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1146 } 1147 } 1148 /* Split edges have 2 vertices and the same faces as the parent */ 1149 for (e = eStart; e < eEnd; ++e) { 1150 for (r = 0; r < 2; ++r) { 1151 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1152 PetscInt size; 1153 1154 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1155 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1156 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1157 } 1158 } 1159 /* Face edges have 2 vertices and 2+cells faces */ 1160 for (f = fStart; f < fEnd; ++f) { 1161 for (r = 0; r < 4; ++r) { 1162 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 1163 PetscInt size; 1164 1165 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1166 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1167 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1168 } 1169 } 1170 /* Cell edges have 2 vertices and 4 faces */ 1171 for (c = cStart; c < cEnd; ++c) { 1172 for (r = 0; r < 6; ++r) { 1173 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 1174 1175 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1176 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1177 } 1178 } 1179 /* Old vertices have identical supports */ 1180 for (v = vStart; v < vEnd; ++v) { 1181 const PetscInt newp = vStartNew + (v - vStart); 1182 PetscInt size; 1183 1184 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1185 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1186 } 1187 /* Edge vertices have 2 + faces supports */ 1188 for (e = eStart; e < eEnd; ++e) { 1189 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1190 PetscInt size; 1191 1192 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1193 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1194 } 1195 /* Face vertices have 4 + cells supports */ 1196 for (f = fStart; f < fEnd; ++f) { 1197 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 1198 PetscInt size; 1199 1200 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1201 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1202 } 1203 /* Cell vertices have 6 supports */ 1204 for (c = cStart; c < cEnd; ++c) { 1205 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 1206 1207 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1208 } 1209 break; 1210 case REFINER_HYBRID_HEX_3D: 1211 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 1212 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1213 /* Interior cells have 6 faces */ 1214 for (c = cStart; c < cMax; ++c) { 1215 for (r = 0; r < 8; ++r) { 1216 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1217 1218 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1219 } 1220 } 1221 /* Hybrid cells have 6 faces */ 1222 for (c = cMax; c < cEnd; ++c) { 1223 for (r = 0; r < 4; ++r) { 1224 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1225 1226 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1227 } 1228 } 1229 /* Interior split faces have 4 edges and the same cells as the parent */ 1230 for (f = fStart; f < fMax; ++f) { 1231 for (r = 0; r < 4; ++r) { 1232 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1233 PetscInt size; 1234 1235 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1236 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1237 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1238 } 1239 } 1240 /* Interior cell faces have 4 edges and 2 cells */ 1241 for (c = cStart; c < cMax; ++c) { 1242 for (r = 0; r < 12; ++r) { 1243 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1244 1245 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1246 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1247 } 1248 } 1249 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1250 for (f = fMax; f < fEnd; ++f) { 1251 for (r = 0; r < 2; ++r) { 1252 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1253 PetscInt size; 1254 1255 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1256 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1257 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1258 } 1259 } 1260 /* Hybrid cells faces have 4 edges and 2 cells */ 1261 for (c = cMax; c < cEnd; ++c) { 1262 for (r = 0; r < 4; ++r) { 1263 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1264 1265 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1266 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1267 } 1268 } 1269 /* Interior split edges have 2 vertices and the same faces as the parent */ 1270 for (e = eStart; e < eMax; ++e) { 1271 for (r = 0; r < 2; ++r) { 1272 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1273 PetscInt size; 1274 1275 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1276 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1277 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1278 } 1279 } 1280 /* Interior face edges have 2 vertices and 2+cells faces */ 1281 for (f = fStart; f < fMax; ++f) { 1282 for (r = 0; r < 4; ++r) { 1283 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1284 PetscInt size; 1285 1286 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1287 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1288 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1289 } 1290 } 1291 /* Interior cell edges have 2 vertices and 4 faces */ 1292 for (c = cStart; c < cMax; ++c) { 1293 for (r = 0; r < 6; ++r) { 1294 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1295 1296 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1297 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1298 } 1299 } 1300 /* Hybrid edges have 2 vertices and the same faces */ 1301 for (e = eMax; e < eEnd; ++e) { 1302 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1303 PetscInt size; 1304 1305 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1306 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1307 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1308 } 1309 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1310 for (f = fMax; f < fEnd; ++f) { 1311 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1312 PetscInt size; 1313 1314 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1315 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1316 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1317 } 1318 /* Hybrid cell edges have 2 vertices and 4 faces */ 1319 for (c = cMax; c < cEnd; ++c) { 1320 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1321 1322 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1323 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1324 } 1325 /* Interior vertices have identical supports */ 1326 for (v = vStart; v < vEnd; ++v) { 1327 const PetscInt newp = vStartNew + (v - vStart); 1328 PetscInt size; 1329 1330 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1331 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1332 } 1333 /* Interior edge vertices have 2 + faces supports */ 1334 for (e = eStart; e < eMax; ++e) { 1335 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1336 PetscInt size; 1337 1338 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1339 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1340 } 1341 /* Interior face vertices have 4 + cells supports */ 1342 for (f = fStart; f < fMax; ++f) { 1343 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1344 PetscInt size; 1345 1346 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1347 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1348 } 1349 /* Interior cell vertices have 6 supports */ 1350 for (c = cStart; c < cMax; ++c) { 1351 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1352 1353 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1354 } 1355 break; 1356 default: 1357 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1358 } 1359 PetscFunctionReturn(0); 1360 } 1361 1362 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1363 { 1364 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1365 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1366 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1367 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 1368 PetscErrorCode ierr; 1369 1370 PetscFunctionBegin; 1371 if (!refiner) PetscFunctionReturn(0); 1372 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1373 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1374 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1375 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1376 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1377 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1378 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1379 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1380 switch (refiner) { 1381 case REFINER_SIMPLEX_1D: 1382 /* Max support size of refined mesh is 2 */ 1383 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1384 /* All cells have 2 vertices */ 1385 for (c = cStart; c < cEnd; ++c) { 1386 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1387 1388 for (r = 0; r < 2; ++r) { 1389 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1390 const PetscInt *cone; 1391 PetscInt coneNew[2]; 1392 1393 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1394 coneNew[0] = vStartNew + (cone[0] - vStart); 1395 coneNew[1] = vStartNew + (cone[1] - vStart); 1396 coneNew[(r+1)%2] = newv; 1397 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1398 #if 1 1399 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew); 1400 for (p = 0; p < 2; ++p) { 1401 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); 1402 } 1403 #endif 1404 } 1405 } 1406 /* Old vertices have identical supports */ 1407 for (v = vStart; v < vEnd; ++v) { 1408 const PetscInt newp = vStartNew + (v - vStart); 1409 const PetscInt *support, *cone; 1410 PetscInt size, s; 1411 1412 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1413 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1414 for (s = 0; s < size; ++s) { 1415 PetscInt r = 0; 1416 1417 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1418 if (cone[1] == v) r = 1; 1419 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1420 } 1421 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1422 #if 1 1423 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1424 for (p = 0; p < size; ++p) { 1425 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); 1426 } 1427 #endif 1428 } 1429 /* Cell vertices have support of 2 cells */ 1430 for (c = cStart; c < cEnd; ++c) { 1431 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1432 1433 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1434 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1435 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1436 #if 1 1437 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1438 for (p = 0; p < 2; ++p) { 1439 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); 1440 } 1441 #endif 1442 } 1443 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1444 break; 1445 case REFINER_SIMPLEX_2D: 1446 /* 1447 2 1448 |\ 1449 | \ 1450 | \ 1451 | \ 1452 | C \ 1453 | \ 1454 | \ 1455 2---1---1 1456 |\ D / \ 1457 | 2 0 \ 1458 |A \ / B \ 1459 0---0-------1 1460 */ 1461 /* All cells have 3 faces */ 1462 for (c = cStart; c < cEnd; ++c) { 1463 const PetscInt newp = cStartNew + (c - cStart)*4; 1464 const PetscInt *cone, *ornt; 1465 PetscInt coneNew[3], orntNew[3]; 1466 1467 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1468 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1469 /* A triangle */ 1470 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1471 orntNew[0] = ornt[0]; 1472 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1473 orntNew[1] = -2; 1474 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1475 orntNew[2] = ornt[2]; 1476 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1477 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1478 #if 1 1479 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); 1480 for (p = 0; p < 3; ++p) { 1481 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); 1482 } 1483 #endif 1484 /* B triangle */ 1485 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1486 orntNew[0] = ornt[0]; 1487 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1488 orntNew[1] = ornt[1]; 1489 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1490 orntNew[2] = -2; 1491 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1492 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1493 #if 1 1494 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); 1495 for (p = 0; p < 3; ++p) { 1496 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); 1497 } 1498 #endif 1499 /* C triangle */ 1500 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1501 orntNew[0] = -2; 1502 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1503 orntNew[1] = ornt[1]; 1504 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1505 orntNew[2] = ornt[2]; 1506 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1507 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1508 #if 1 1509 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); 1510 for (p = 0; p < 3; ++p) { 1511 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); 1512 } 1513 #endif 1514 /* D triangle */ 1515 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1516 orntNew[0] = 0; 1517 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1518 orntNew[1] = 0; 1519 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1520 orntNew[2] = 0; 1521 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1522 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1523 #if 1 1524 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); 1525 for (p = 0; p < 3; ++p) { 1526 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); 1527 } 1528 #endif 1529 } 1530 /* Split faces have 2 vertices and the same cells as the parent */ 1531 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1532 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1533 for (f = fStart; f < fEnd; ++f) { 1534 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1535 1536 for (r = 0; r < 2; ++r) { 1537 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1538 const PetscInt *cone, *ornt, *support; 1539 PetscInt coneNew[2], coneSize, c, supportSize, s; 1540 1541 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1542 coneNew[0] = vStartNew + (cone[0] - vStart); 1543 coneNew[1] = vStartNew + (cone[1] - vStart); 1544 coneNew[(r+1)%2] = newv; 1545 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1546 #if 1 1547 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1548 for (p = 0; p < 2; ++p) { 1549 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); 1550 } 1551 #endif 1552 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1553 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1554 for (s = 0; s < supportSize; ++s) { 1555 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1556 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1557 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1558 for (c = 0; c < coneSize; ++c) { 1559 if (cone[c] == f) break; 1560 } 1561 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1562 } 1563 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1564 #if 1 1565 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1566 for (p = 0; p < supportSize; ++p) { 1567 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); 1568 } 1569 #endif 1570 } 1571 } 1572 /* Interior faces have 2 vertices and 2 cells */ 1573 for (c = cStart; c < cEnd; ++c) { 1574 const PetscInt *cone; 1575 1576 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1577 for (r = 0; r < 3; ++r) { 1578 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1579 PetscInt coneNew[2]; 1580 PetscInt supportNew[2]; 1581 1582 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1583 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1584 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1585 #if 1 1586 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1587 for (p = 0; p < 2; ++p) { 1588 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); 1589 } 1590 #endif 1591 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1592 supportNew[1] = (c - cStart)*4 + 3; 1593 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1594 #if 1 1595 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1596 for (p = 0; p < 2; ++p) { 1597 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); 1598 } 1599 #endif 1600 } 1601 } 1602 /* Old vertices have identical supports */ 1603 for (v = vStart; v < vEnd; ++v) { 1604 const PetscInt newp = vStartNew + (v - vStart); 1605 const PetscInt *support, *cone; 1606 PetscInt size, s; 1607 1608 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1609 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1610 for (s = 0; s < size; ++s) { 1611 PetscInt r = 0; 1612 1613 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1614 if (cone[1] == v) r = 1; 1615 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1616 } 1617 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1618 #if 1 1619 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1620 for (p = 0; p < size; ++p) { 1621 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); 1622 } 1623 #endif 1624 } 1625 /* Face vertices have 2 + cells*2 supports */ 1626 for (f = fStart; f < fEnd; ++f) { 1627 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1628 const PetscInt *cone, *support; 1629 PetscInt size, s; 1630 1631 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1632 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1633 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1634 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1635 for (s = 0; s < size; ++s) { 1636 PetscInt r = 0; 1637 1638 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1639 if (cone[1] == f) r = 1; 1640 else if (cone[2] == f) r = 2; 1641 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1642 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1643 } 1644 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1645 #if 1 1646 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1647 for (p = 0; p < 2+size*2; ++p) { 1648 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); 1649 } 1650 #endif 1651 } 1652 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1653 break; 1654 case REFINER_SIMPLEX_TO_HEX_2D: 1655 /* 1656 2 1657 |\ 1658 | \ 1659 | \ 1660 | \ 1661 | C \ 1662 | \ 1663 2 1 1664 |\ / \ 1665 | 2 1 \ 1666 | \/ \ 1667 | | \ 1668 |A | B \ 1669 | 0 \ 1670 | | \ 1671 0---0----------1 1672 */ 1673 /* All cells have 4 faces */ 1674 for (c = cStart; c < cEnd; ++c) { 1675 const PetscInt newp = cStartNew + (c - cStart)*3; 1676 const PetscInt *cone, *ornt; 1677 PetscInt coneNew[4], orntNew[4]; 1678 1679 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1680 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1681 /* A quad */ 1682 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1683 orntNew[0] = ornt[0]; 1684 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1685 orntNew[1] = 0; 1686 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1687 orntNew[2] = -2; 1688 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1689 orntNew[3] = ornt[2]; 1690 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1691 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1692 #if 1 1693 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); 1694 for (p = 0; p < 4; ++p) { 1695 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); 1696 } 1697 #endif 1698 /* B quad */ 1699 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1700 orntNew[0] = ornt[0]; 1701 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1702 orntNew[1] = ornt[1]; 1703 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1704 orntNew[2] = 0; 1705 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1706 orntNew[3] = -2; 1707 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1708 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1709 #if 1 1710 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); 1711 for (p = 0; p < 4; ++p) { 1712 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); 1713 } 1714 #endif 1715 /* C quad */ 1716 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1717 orntNew[0] = ornt[1]; 1718 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1719 orntNew[1] = ornt[2]; 1720 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1721 orntNew[2] = 0; 1722 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1723 orntNew[3] = -2; 1724 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1725 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1726 #if 1 1727 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); 1728 for (p = 0; p < 4; ++p) { 1729 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); 1730 } 1731 #endif 1732 } 1733 /* Split faces have 2 vertices and the same cells as the parent */ 1734 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1735 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1736 for (f = fStart; f < fEnd; ++f) { 1737 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1738 1739 for (r = 0; r < 2; ++r) { 1740 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1741 const PetscInt *cone, *ornt, *support; 1742 PetscInt coneNew[2], coneSize, c, supportSize, s; 1743 1744 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1745 coneNew[0] = vStartNew + (cone[0] - vStart); 1746 coneNew[1] = vStartNew + (cone[1] - vStart); 1747 coneNew[(r+1)%2] = newv; 1748 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1749 #if 1 1750 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1751 for (p = 0; p < 2; ++p) { 1752 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); 1753 } 1754 #endif 1755 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1756 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1757 for (s = 0; s < supportSize; ++s) { 1758 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1759 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1760 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1761 for (c = 0; c < coneSize; ++c) { 1762 if (cone[c] == f) break; 1763 } 1764 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1765 } 1766 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1767 #if 1 1768 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1769 for (p = 0; p < supportSize; ++p) { 1770 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); 1771 } 1772 #endif 1773 } 1774 } 1775 /* Interior faces have 2 vertices and 2 cells */ 1776 for (c = cStart; c < cEnd; ++c) { 1777 const PetscInt *cone; 1778 1779 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1780 for (r = 0; r < 3; ++r) { 1781 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1782 PetscInt coneNew[2]; 1783 PetscInt supportNew[2]; 1784 1785 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1786 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 1787 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1788 #if 1 1789 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1790 for (p = 0; p < 2; ++p) { 1791 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1792 } 1793 #endif 1794 supportNew[0] = (c - cStart)*3 + r%3; 1795 supportNew[1] = (c - cStart)*3 + (r+1)%3; 1796 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1797 #if 1 1798 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1799 for (p = 0; p < 2; ++p) { 1800 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); 1801 } 1802 #endif 1803 } 1804 } 1805 /* Old vertices have identical supports */ 1806 for (v = vStart; v < vEnd; ++v) { 1807 const PetscInt newp = vStartNew + (v - vStart); 1808 const PetscInt *support, *cone; 1809 PetscInt size, s; 1810 1811 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1812 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1813 for (s = 0; s < size; ++s) { 1814 PetscInt r = 0; 1815 1816 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1817 if (cone[1] == v) r = 1; 1818 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1819 } 1820 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1821 #if 1 1822 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1823 for (p = 0; p < size; ++p) { 1824 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); 1825 } 1826 #endif 1827 } 1828 /* Split-face vertices have cells + 2 supports */ 1829 for (f = fStart; f < fEnd; ++f) { 1830 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1831 const PetscInt *cone, *support; 1832 PetscInt size, s; 1833 1834 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1835 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1836 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1837 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1838 for (s = 0; s < size; ++s) { 1839 PetscInt r = 0; 1840 1841 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1842 if (cone[1] == f) r = 1; 1843 else if (cone[2] == f) r = 2; 1844 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1845 } 1846 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1847 #if 1 1848 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1849 for (p = 0; p < 2+size; ++p) { 1850 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); 1851 } 1852 #endif 1853 } 1854 /* Interior vertices vertices have 3 supports */ 1855 for (c = cStart; c < cEnd; ++c) { 1856 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 1857 1858 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1859 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1860 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1861 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1862 } 1863 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1864 break; 1865 case REFINER_HEX_2D: 1866 /* 1867 3---------2---------2 1868 | | | 1869 | D 2 C | 1870 | | | 1871 3----3----0----1----1 1872 | | | 1873 | A 0 B | 1874 | | | 1875 0---------0---------1 1876 */ 1877 /* All cells have 4 faces */ 1878 for (c = cStart; c < cEnd; ++c) { 1879 const PetscInt newp = (c - cStart)*4; 1880 const PetscInt *cone, *ornt; 1881 PetscInt coneNew[4], orntNew[4]; 1882 1883 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1884 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1885 /* A quad */ 1886 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1887 orntNew[0] = ornt[0]; 1888 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1889 orntNew[1] = 0; 1890 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1891 orntNew[2] = -2; 1892 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 1893 orntNew[3] = ornt[3]; 1894 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1895 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1896 #if 1 1897 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); 1898 for (p = 0; p < 4; ++p) { 1899 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); 1900 } 1901 #endif 1902 /* B quad */ 1903 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1904 orntNew[0] = ornt[0]; 1905 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1906 orntNew[1] = ornt[1]; 1907 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1908 orntNew[2] = -2; 1909 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 1910 orntNew[3] = -2; 1911 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1912 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1913 #if 1 1914 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); 1915 for (p = 0; p < 4; ++p) { 1916 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); 1917 } 1918 #endif 1919 /* C quad */ 1920 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 1921 orntNew[0] = 0; 1922 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1923 orntNew[1] = ornt[1]; 1924 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1925 orntNew[2] = ornt[2]; 1926 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1927 orntNew[3] = -2; 1928 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1929 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1930 #if 1 1931 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); 1932 for (p = 0; p < 4; ++p) { 1933 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); 1934 } 1935 #endif 1936 /* D quad */ 1937 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 1938 orntNew[0] = 0; 1939 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 1940 orntNew[1] = 0; 1941 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1942 orntNew[2] = ornt[2]; 1943 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 1944 orntNew[3] = ornt[3]; 1945 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1946 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1947 #if 1 1948 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); 1949 for (p = 0; p < 4; ++p) { 1950 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); 1951 } 1952 #endif 1953 } 1954 /* Split faces have 2 vertices and the same cells as the parent */ 1955 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1956 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1957 for (f = fStart; f < fEnd; ++f) { 1958 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1959 1960 for (r = 0; r < 2; ++r) { 1961 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1962 const PetscInt *cone, *ornt, *support; 1963 PetscInt coneNew[2], coneSize, c, supportSize, s; 1964 1965 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1966 coneNew[0] = vStartNew + (cone[0] - vStart); 1967 coneNew[1] = vStartNew + (cone[1] - vStart); 1968 coneNew[(r+1)%2] = newv; 1969 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1970 #if 1 1971 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1972 for (p = 0; p < 2; ++p) { 1973 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); 1974 } 1975 #endif 1976 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1977 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1978 for (s = 0; s < supportSize; ++s) { 1979 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1980 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1981 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1982 for (c = 0; c < coneSize; ++c) { 1983 if (cone[c] == f) break; 1984 } 1985 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 1986 } 1987 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1988 #if 1 1989 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1990 for (p = 0; p < supportSize; ++p) { 1991 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); 1992 } 1993 #endif 1994 } 1995 } 1996 /* Interior faces have 2 vertices and 2 cells */ 1997 for (c = cStart; c < cEnd; ++c) { 1998 const PetscInt *cone; 1999 PetscInt coneNew[2], supportNew[2]; 2000 2001 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2002 for (r = 0; r < 4; ++r) { 2003 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2004 2005 if (r==1 || r==2) { 2006 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2007 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2008 } else { 2009 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2010 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2011 } 2012 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2013 #if 1 2014 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2015 for (p = 0; p < 2; ++p) { 2016 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); 2017 } 2018 #endif 2019 supportNew[0] = (c - cStart)*4 + r; 2020 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2021 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2022 #if 1 2023 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2024 for (p = 0; p < 2; ++p) { 2025 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); 2026 } 2027 #endif 2028 } 2029 } 2030 /* Old vertices have identical supports */ 2031 for (v = vStart; v < vEnd; ++v) { 2032 const PetscInt newp = vStartNew + (v - vStart); 2033 const PetscInt *support, *cone; 2034 PetscInt size, s; 2035 2036 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2037 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2038 for (s = 0; s < size; ++s) { 2039 PetscInt r = 0; 2040 2041 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2042 if (cone[1] == v) r = 1; 2043 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2044 } 2045 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2046 #if 1 2047 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2048 for (p = 0; p < size; ++p) { 2049 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); 2050 } 2051 #endif 2052 } 2053 /* Face vertices have 2 + cells supports */ 2054 for (f = fStart; f < fEnd; ++f) { 2055 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2056 const PetscInt *cone, *support; 2057 PetscInt size, s; 2058 2059 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2060 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2061 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2062 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2063 for (s = 0; s < size; ++s) { 2064 PetscInt r = 0; 2065 2066 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2067 if (cone[1] == f) r = 1; 2068 else if (cone[2] == f) r = 2; 2069 else if (cone[3] == f) r = 3; 2070 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 2071 } 2072 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2073 #if 1 2074 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2075 for (p = 0; p < 2+size; ++p) { 2076 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); 2077 } 2078 #endif 2079 } 2080 /* Cell vertices have 4 supports */ 2081 for (c = cStart; c < cEnd; ++c) { 2082 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2083 PetscInt supportNew[4]; 2084 2085 for (r = 0; r < 4; ++r) { 2086 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2087 } 2088 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2089 } 2090 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2091 break; 2092 case REFINER_HYBRID_SIMPLEX_2D: 2093 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2094 cMax = PetscMin(cEnd, cMax); 2095 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2096 fMax = PetscMin(fEnd, fMax); 2097 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2098 /* Interior cells have 3 faces */ 2099 for (c = cStart; c < cMax; ++c) { 2100 const PetscInt newp = cStartNew + (c - cStart)*4; 2101 const PetscInt *cone, *ornt; 2102 PetscInt coneNew[3], orntNew[3]; 2103 2104 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2105 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2106 /* A triangle */ 2107 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2108 orntNew[0] = ornt[0]; 2109 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2110 orntNew[1] = -2; 2111 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2112 orntNew[2] = ornt[2]; 2113 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2114 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2115 #if 1 2116 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); 2117 for (p = 0; p < 3; ++p) { 2118 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); 2119 } 2120 #endif 2121 /* B triangle */ 2122 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2123 orntNew[0] = ornt[0]; 2124 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2125 orntNew[1] = ornt[1]; 2126 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2127 orntNew[2] = -2; 2128 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2129 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2130 #if 1 2131 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); 2132 for (p = 0; p < 3; ++p) { 2133 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); 2134 } 2135 #endif 2136 /* C triangle */ 2137 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2138 orntNew[0] = -2; 2139 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2140 orntNew[1] = ornt[1]; 2141 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2142 orntNew[2] = ornt[2]; 2143 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2144 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2145 #if 1 2146 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); 2147 for (p = 0; p < 3; ++p) { 2148 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); 2149 } 2150 #endif 2151 /* D triangle */ 2152 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2153 orntNew[0] = 0; 2154 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2155 orntNew[1] = 0; 2156 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2157 orntNew[2] = 0; 2158 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2159 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2160 #if 1 2161 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); 2162 for (p = 0; p < 3; ++p) { 2163 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); 2164 } 2165 #endif 2166 } 2167 /* 2168 2----3----3 2169 | | 2170 | B | 2171 | | 2172 0----4--- 1 2173 | | 2174 | A | 2175 | | 2176 0----2----1 2177 */ 2178 /* Hybrid cells have 4 faces */ 2179 for (c = cMax; c < cEnd; ++c) { 2180 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2181 const PetscInt *cone, *ornt; 2182 PetscInt coneNew[4], orntNew[4], r; 2183 2184 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2185 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2186 r = (ornt[0] < 0 ? 1 : 0); 2187 /* A quad */ 2188 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2189 orntNew[0] = ornt[0]; 2190 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2191 orntNew[1] = ornt[1]; 2192 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2193 orntNew[2+r] = 0; 2194 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2195 orntNew[3-r] = 0; 2196 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2197 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2198 #if 1 2199 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); 2200 for (p = 0; p < 4; ++p) { 2201 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); 2202 } 2203 #endif 2204 /* B quad */ 2205 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2206 orntNew[0] = ornt[0]; 2207 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2208 orntNew[1] = ornt[1]; 2209 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2210 orntNew[2+r] = 0; 2211 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2212 orntNew[3-r] = 0; 2213 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2214 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2215 #if 1 2216 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); 2217 for (p = 0; p < 4; ++p) { 2218 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); 2219 } 2220 #endif 2221 } 2222 /* Interior split faces have 2 vertices and the same cells as the parent */ 2223 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2224 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2225 for (f = fStart; f < fMax; ++f) { 2226 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2227 2228 for (r = 0; r < 2; ++r) { 2229 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2230 const PetscInt *cone, *ornt, *support; 2231 PetscInt coneNew[2], coneSize, c, supportSize, s; 2232 2233 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2234 coneNew[0] = vStartNew + (cone[0] - vStart); 2235 coneNew[1] = vStartNew + (cone[1] - vStart); 2236 coneNew[(r+1)%2] = newv; 2237 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2238 #if 1 2239 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2240 for (p = 0; p < 2; ++p) { 2241 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); 2242 } 2243 #endif 2244 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2245 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2246 for (s = 0; s < supportSize; ++s) { 2247 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2248 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2249 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2250 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2251 if (support[s] >= cMax) { 2252 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2253 } else { 2254 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2255 } 2256 } 2257 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2258 #if 1 2259 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2260 for (p = 0; p < supportSize; ++p) { 2261 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); 2262 } 2263 #endif 2264 } 2265 } 2266 /* Interior cell faces have 2 vertices and 2 cells */ 2267 for (c = cStart; c < cMax; ++c) { 2268 const PetscInt *cone; 2269 2270 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2271 for (r = 0; r < 3; ++r) { 2272 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 2273 PetscInt coneNew[2]; 2274 PetscInt supportNew[2]; 2275 2276 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2277 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 2278 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2279 #if 1 2280 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2281 for (p = 0; p < 2; ++p) { 2282 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); 2283 } 2284 #endif 2285 supportNew[0] = (c - cStart)*4 + (r+1)%3; 2286 supportNew[1] = (c - cStart)*4 + 3; 2287 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2288 #if 1 2289 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2290 for (p = 0; p < 2; ++p) { 2291 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); 2292 } 2293 #endif 2294 } 2295 } 2296 /* Interior hybrid faces have 2 vertices and the same cells */ 2297 for (f = fMax; f < fEnd; ++f) { 2298 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 2299 const PetscInt *cone, *ornt; 2300 const PetscInt *support; 2301 PetscInt coneNew[2]; 2302 PetscInt supportNew[2]; 2303 PetscInt size, s, r; 2304 2305 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2306 coneNew[0] = vStartNew + (cone[0] - vStart); 2307 coneNew[1] = vStartNew + (cone[1] - vStart); 2308 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2309 #if 1 2310 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2311 for (p = 0; p < 2; ++p) { 2312 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); 2313 } 2314 #endif 2315 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2316 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2317 for (s = 0; s < size; ++s) { 2318 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2319 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2320 for (r = 0; r < 2; ++r) { 2321 if (cone[r+2] == f) break; 2322 } 2323 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 2324 } 2325 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2326 #if 1 2327 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2328 for (p = 0; p < size; ++p) { 2329 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); 2330 } 2331 #endif 2332 } 2333 /* Cell hybrid faces have 2 vertices and 2 cells */ 2334 for (c = cMax; c < cEnd; ++c) { 2335 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2336 const PetscInt *cone; 2337 PetscInt coneNew[2]; 2338 PetscInt supportNew[2]; 2339 2340 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2341 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2342 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2343 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2344 #if 1 2345 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2346 for (p = 0; p < 2; ++p) { 2347 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); 2348 } 2349 #endif 2350 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2351 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2352 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2353 #if 1 2354 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2355 for (p = 0; p < 2; ++p) { 2356 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); 2357 } 2358 #endif 2359 } 2360 /* Old vertices have identical supports */ 2361 for (v = vStart; v < vEnd; ++v) { 2362 const PetscInt newp = vStartNew + (v - vStart); 2363 const PetscInt *support, *cone; 2364 PetscInt size, s; 2365 2366 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2367 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2368 for (s = 0; s < size; ++s) { 2369 if (support[s] >= fMax) { 2370 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 2371 } else { 2372 PetscInt r = 0; 2373 2374 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2375 if (cone[1] == v) r = 1; 2376 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2377 } 2378 } 2379 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2380 #if 1 2381 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2382 for (p = 0; p < size; ++p) { 2383 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); 2384 } 2385 #endif 2386 } 2387 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 2388 for (f = fStart; f < fMax; ++f) { 2389 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2390 const PetscInt *cone, *support; 2391 PetscInt size, newSize = 2, s; 2392 2393 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2394 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2395 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2396 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2397 for (s = 0; s < size; ++s) { 2398 PetscInt r = 0; 2399 2400 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2401 if (support[s] >= cMax) { 2402 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 2403 2404 newSize += 1; 2405 } else { 2406 if (cone[1] == f) r = 1; 2407 else if (cone[2] == f) r = 2; 2408 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 2409 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 2410 2411 newSize += 2; 2412 } 2413 } 2414 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2415 #if 1 2416 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2417 for (p = 0; p < newSize; ++p) { 2418 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); 2419 } 2420 #endif 2421 } 2422 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2423 break; 2424 case REFINER_HYBRID_HEX_2D: 2425 /* Hybrid Hex 2D */ 2426 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2427 cMax = PetscMin(cEnd, cMax); 2428 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2429 fMax = PetscMin(fEnd, fMax); 2430 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2431 /* Interior cells have 4 faces */ 2432 for (c = cStart; c < cMax; ++c) { 2433 const PetscInt newp = cStartNew + (c - cStart)*4; 2434 const PetscInt *cone, *ornt; 2435 PetscInt coneNew[4], orntNew[4]; 2436 2437 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2438 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2439 /* A quad */ 2440 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2441 orntNew[0] = ornt[0]; 2442 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 2443 orntNew[1] = 0; 2444 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2445 orntNew[2] = -2; 2446 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2447 orntNew[3] = ornt[3]; 2448 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2449 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2450 #if 1 2451 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); 2452 for (p = 0; p < 4; ++p) { 2453 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); 2454 } 2455 #endif 2456 /* B quad */ 2457 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2458 orntNew[0] = ornt[0]; 2459 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2460 orntNew[1] = ornt[1]; 2461 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2462 orntNew[2] = 0; 2463 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 2464 orntNew[3] = -2; 2465 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2466 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2467 #if 1 2468 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); 2469 for (p = 0; p < 4; ++p) { 2470 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); 2471 } 2472 #endif 2473 /* C quad */ 2474 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 2475 orntNew[0] = -2; 2476 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2477 orntNew[1] = ornt[1]; 2478 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2479 orntNew[2] = ornt[2]; 2480 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2481 orntNew[3] = 0; 2482 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2483 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2484 #if 1 2485 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); 2486 for (p = 0; p < 4; ++p) { 2487 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); 2488 } 2489 #endif 2490 /* D quad */ 2491 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 2492 orntNew[0] = 0; 2493 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 2494 orntNew[1] = -2; 2495 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2496 orntNew[2] = ornt[2]; 2497 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2498 orntNew[3] = ornt[3]; 2499 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2500 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2501 #if 1 2502 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); 2503 for (p = 0; p < 4; ++p) { 2504 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); 2505 } 2506 #endif 2507 } 2508 /* 2509 2----3----3 2510 | | 2511 | B | 2512 | | 2513 0----4--- 1 2514 | | 2515 | A | 2516 | | 2517 0----2----1 2518 */ 2519 /* Hybrid cells have 4 faces */ 2520 for (c = cMax; c < cEnd; ++c) { 2521 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2522 const PetscInt *cone, *ornt; 2523 PetscInt coneNew[4], orntNew[4]; 2524 2525 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2526 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2527 /* A quad */ 2528 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2529 orntNew[0] = ornt[0]; 2530 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2531 orntNew[1] = ornt[1]; 2532 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 2533 orntNew[2] = 0; 2534 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2535 orntNew[3] = 0; 2536 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2537 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2538 #if 1 2539 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); 2540 for (p = 0; p < 4; ++p) { 2541 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); 2542 } 2543 #endif 2544 /* B quad */ 2545 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2546 orntNew[0] = ornt[0]; 2547 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2548 orntNew[1] = ornt[1]; 2549 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2550 orntNew[2] = 0; 2551 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 2552 orntNew[3] = 0; 2553 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2554 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2555 #if 1 2556 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); 2557 for (p = 0; p < 4; ++p) { 2558 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); 2559 } 2560 #endif 2561 } 2562 /* Interior split faces have 2 vertices and the same cells as the parent */ 2563 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2564 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2565 for (f = fStart; f < fMax; ++f) { 2566 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2567 2568 for (r = 0; r < 2; ++r) { 2569 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2570 const PetscInt *cone, *ornt, *support; 2571 PetscInt coneNew[2], coneSize, c, supportSize, s; 2572 2573 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2574 coneNew[0] = vStartNew + (cone[0] - vStart); 2575 coneNew[1] = vStartNew + (cone[1] - vStart); 2576 coneNew[(r+1)%2] = newv; 2577 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2578 #if 1 2579 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2580 for (p = 0; p < 2; ++p) { 2581 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); 2582 } 2583 #endif 2584 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2585 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2586 for (s = 0; s < supportSize; ++s) { 2587 if (support[s] >= cMax) { 2588 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2589 } else { 2590 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2591 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2592 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2593 for (c = 0; c < coneSize; ++c) { 2594 if (cone[c] == f) break; 2595 } 2596 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2597 } 2598 } 2599 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2600 #if 1 2601 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2602 for (p = 0; p < supportSize; ++p) { 2603 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); 2604 } 2605 #endif 2606 } 2607 } 2608 /* Interior cell faces have 2 vertices and 2 cells */ 2609 for (c = cStart; c < cMax; ++c) { 2610 const PetscInt *cone; 2611 2612 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2613 for (r = 0; r < 4; ++r) { 2614 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2615 PetscInt coneNew[2], supportNew[2]; 2616 2617 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2618 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2619 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2620 #if 1 2621 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2622 for (p = 0; p < 2; ++p) { 2623 if ((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); 2624 } 2625 #endif 2626 supportNew[0] = (c - cStart)*4 + r; 2627 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2628 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2629 #if 1 2630 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2631 for (p = 0; p < 2; ++p) { 2632 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); 2633 } 2634 #endif 2635 } 2636 } 2637 /* Hybrid faces have 2 vertices and the same cells */ 2638 for (f = fMax; f < fEnd; ++f) { 2639 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 2640 const PetscInt *cone, *support; 2641 PetscInt coneNew[2], supportNew[2]; 2642 PetscInt size, s, r; 2643 2644 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2645 coneNew[0] = vStartNew + (cone[0] - vStart); 2646 coneNew[1] = vStartNew + (cone[1] - vStart); 2647 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2648 #if 1 2649 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2650 for (p = 0; p < 2; ++p) { 2651 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); 2652 } 2653 #endif 2654 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2655 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2656 for (s = 0; s < size; ++s) { 2657 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2658 for (r = 0; r < 2; ++r) { 2659 if (cone[r+2] == f) break; 2660 } 2661 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 2662 } 2663 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2664 #if 1 2665 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2666 for (p = 0; p < size; ++p) { 2667 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); 2668 } 2669 #endif 2670 } 2671 /* Cell hybrid faces have 2 vertices and 2 cells */ 2672 for (c = cMax; c < cEnd; ++c) { 2673 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 2674 const PetscInt *cone; 2675 PetscInt coneNew[2], supportNew[2]; 2676 2677 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2678 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2679 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2680 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2681 #if 1 2682 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2683 for (p = 0; p < 2; ++p) { 2684 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); 2685 } 2686 #endif 2687 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2688 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2689 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2690 #if 1 2691 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2692 for (p = 0; p < 2; ++p) { 2693 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); 2694 } 2695 #endif 2696 } 2697 /* Old vertices have identical supports */ 2698 for (v = vStart; v < vEnd; ++v) { 2699 const PetscInt newp = vStartNew + (v - vStart); 2700 const PetscInt *support, *cone; 2701 PetscInt size, s; 2702 2703 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2704 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2705 for (s = 0; s < size; ++s) { 2706 if (support[s] >= fMax) { 2707 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 2708 } else { 2709 PetscInt r = 0; 2710 2711 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2712 if (cone[1] == v) r = 1; 2713 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2714 } 2715 } 2716 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2717 #if 1 2718 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2719 for (p = 0; p < size; ++p) { 2720 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); 2721 } 2722 #endif 2723 } 2724 /* Face vertices have 2 + cells supports */ 2725 for (f = fStart; f < fMax; ++f) { 2726 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2727 const PetscInt *cone, *support; 2728 PetscInt size, s; 2729 2730 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2731 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2732 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2733 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2734 for (s = 0; s < size; ++s) { 2735 PetscInt r = 0; 2736 2737 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2738 if (support[s] >= cMax) { 2739 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 2740 } else { 2741 if (cone[1] == f) r = 1; 2742 else if (cone[2] == f) r = 2; 2743 else if (cone[3] == f) r = 3; 2744 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 2745 } 2746 } 2747 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2748 #if 1 2749 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2750 for (p = 0; p < 2+size; ++p) { 2751 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); 2752 } 2753 #endif 2754 } 2755 /* Cell vertices have 4 supports */ 2756 for (c = cStart; c < cMax; ++c) { 2757 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 2758 PetscInt supportNew[4]; 2759 2760 for (r = 0; r < 4; ++r) { 2761 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 2762 } 2763 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2764 } 2765 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2766 break; 2767 case REFINER_SIMPLEX_3D: 2768 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 2769 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 2770 for (c = cStart; c < cEnd; ++c) { 2771 const PetscInt newp = cStartNew + (c - cStart)*8; 2772 const PetscInt *cone, *ornt; 2773 PetscInt coneNew[4], orntNew[4]; 2774 2775 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2776 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2777 /* A tetrahedron: {0, a, c, d} */ 2778 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 2779 orntNew[0] = ornt[0]; 2780 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 2781 orntNew[1] = ornt[1]; 2782 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 2783 orntNew[2] = ornt[2]; 2784 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2785 orntNew[3] = 0; 2786 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2787 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2788 #if 1 2789 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); 2790 for (p = 0; p < 4; ++p) { 2791 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); 2792 } 2793 #endif 2794 /* B tetrahedron: {a, 1, b, e} */ 2795 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 2796 orntNew[0] = ornt[0]; 2797 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 2798 orntNew[1] = ornt[1]; 2799 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2800 orntNew[2] = 0; 2801 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 2802 orntNew[3] = ornt[3]; 2803 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2804 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2805 #if 1 2806 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); 2807 for (p = 0; p < 4; ++p) { 2808 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); 2809 } 2810 #endif 2811 /* C tetrahedron: {c, b, 2, f} */ 2812 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 2813 orntNew[0] = ornt[0]; 2814 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2815 orntNew[1] = 0; 2816 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 2817 orntNew[2] = ornt[2]; 2818 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 2819 orntNew[3] = ornt[3]; 2820 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2821 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2822 #if 1 2823 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); 2824 for (p = 0; p < 4; ++p) { 2825 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); 2826 } 2827 #endif 2828 /* D tetrahedron: {d, e, f, 3} */ 2829 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2830 orntNew[0] = 0; 2831 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 2832 orntNew[1] = ornt[1]; 2833 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 2834 orntNew[2] = ornt[2]; 2835 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 2836 orntNew[3] = ornt[3]; 2837 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2838 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2839 #if 1 2840 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); 2841 for (p = 0; p < 4; ++p) { 2842 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); 2843 } 2844 #endif 2845 /* A' tetrahedron: {c, d, a, f} */ 2846 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 2847 orntNew[0] = -3; 2848 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 2849 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 2850 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2851 orntNew[2] = 0; 2852 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2853 orntNew[3] = 2; 2854 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 2855 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 2856 #if 1 2857 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); 2858 for (p = 0; p < 4; ++p) { 2859 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); 2860 } 2861 #endif 2862 /* B' tetrahedron: {e, b, a, f} */ 2863 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 2864 orntNew[0] = -2; 2865 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 2866 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 2867 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2868 orntNew[2] = 0; 2869 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2870 orntNew[3] = 0; 2871 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 2872 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 2873 #if 1 2874 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); 2875 for (p = 0; p < 4; ++p) { 2876 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); 2877 } 2878 #endif 2879 /* C' tetrahedron: {f, a, c, b} */ 2880 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 2881 orntNew[0] = -2; 2882 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 2883 orntNew[1] = -2; 2884 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 2885 orntNew[2] = -1; 2886 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 2887 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 2888 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 2889 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 2890 #if 1 2891 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); 2892 for (p = 0; p < 4; ++p) { 2893 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); 2894 } 2895 #endif 2896 /* D' tetrahedron: {f, a, e, d} */ 2897 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 2898 orntNew[0] = -2; 2899 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 2900 orntNew[1] = -1; 2901 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 2902 orntNew[2] = -2; 2903 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 2904 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 2905 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 2906 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 2907 #if 1 2908 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); 2909 for (p = 0; p < 4; ++p) { 2910 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); 2911 } 2912 #endif 2913 } 2914 /* Split faces have 3 edges and the same cells as the parent */ 2915 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2916 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2917 for (f = fStart; f < fEnd; ++f) { 2918 const PetscInt newp = fStartNew + (f - fStart)*4; 2919 const PetscInt *cone, *ornt, *support; 2920 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 2921 2922 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2923 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 2924 /* A triangle */ 2925 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 2926 orntNew[0] = ornt[0]; 2927 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2928 orntNew[1] = -2; 2929 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 2930 orntNew[2] = ornt[2]; 2931 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2932 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2933 #if 1 2934 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); 2935 for (p = 0; p < 3; ++p) { 2936 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); 2937 } 2938 #endif 2939 /* B triangle */ 2940 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 2941 orntNew[0] = ornt[0]; 2942 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 2943 orntNew[1] = ornt[1]; 2944 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2945 orntNew[2] = -2; 2946 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2947 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2948 #if 1 2949 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); 2950 for (p = 0; p < 3; ++p) { 2951 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); 2952 } 2953 #endif 2954 /* C triangle */ 2955 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2956 orntNew[0] = -2; 2957 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 2958 orntNew[1] = ornt[1]; 2959 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 2960 orntNew[2] = ornt[2]; 2961 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2962 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2963 #if 1 2964 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); 2965 for (p = 0; p < 3; ++p) { 2966 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); 2967 } 2968 #endif 2969 /* D triangle */ 2970 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 2971 orntNew[0] = 0; 2972 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 2973 orntNew[1] = 0; 2974 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 2975 orntNew[2] = 0; 2976 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2977 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2978 #if 1 2979 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); 2980 for (p = 0; p < 3; ++p) { 2981 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); 2982 } 2983 #endif 2984 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2985 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2986 for (r = 0; r < 4; ++r) { 2987 for (s = 0; s < supportSize; ++s) { 2988 PetscInt subf; 2989 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2990 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2991 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2992 for (c = 0; c < coneSize; ++c) { 2993 if (cone[c] == f) break; 2994 } 2995 subf = GetTriSubfaceInverse_Static(ornt[c], r); 2996 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 2997 } 2998 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 2999 #if 1 3000 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); 3001 for (p = 0; p < supportSize; ++p) { 3002 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); 3003 } 3004 #endif 3005 } 3006 } 3007 /* Interior faces have 3 edges and 2 cells */ 3008 for (c = cStart; c < cEnd; ++c) { 3009 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 3010 const PetscInt *cone, *ornt; 3011 PetscInt coneNew[3], orntNew[3]; 3012 PetscInt supportNew[2]; 3013 3014 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3015 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3016 /* Face A: {c, a, d} */ 3017 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3018 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3019 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3020 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3021 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3022 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3023 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3024 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3025 #if 1 3026 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3027 for (p = 0; p < 3; ++p) { 3028 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); 3029 } 3030 #endif 3031 supportNew[0] = (c - cStart)*8 + 0; 3032 supportNew[1] = (c - cStart)*8 + 0+4; 3033 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3034 #if 1 3035 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3036 for (p = 0; p < 2; ++p) { 3037 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); 3038 } 3039 #endif 3040 ++newp; 3041 /* Face B: {a, b, e} */ 3042 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3043 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3044 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3045 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3046 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3047 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3048 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3049 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3050 #if 1 3051 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3052 for (p = 0; p < 3; ++p) { 3053 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); 3054 } 3055 #endif 3056 supportNew[0] = (c - cStart)*8 + 1; 3057 supportNew[1] = (c - cStart)*8 + 1+4; 3058 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3059 #if 1 3060 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3061 for (p = 0; p < 2; ++p) { 3062 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); 3063 } 3064 #endif 3065 ++newp; 3066 /* Face C: {c, f, b} */ 3067 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3068 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3069 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3070 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3071 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3072 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3073 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3074 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3075 #if 1 3076 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3077 for (p = 0; p < 3; ++p) { 3078 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); 3079 } 3080 #endif 3081 supportNew[0] = (c - cStart)*8 + 2; 3082 supportNew[1] = (c - cStart)*8 + 2+4; 3083 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3084 #if 1 3085 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3086 for (p = 0; p < 2; ++p) { 3087 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); 3088 } 3089 #endif 3090 ++newp; 3091 /* Face D: {d, e, f} */ 3092 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3093 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3094 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3095 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3096 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3097 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3098 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3099 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3100 #if 1 3101 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3102 for (p = 0; p < 3; ++p) { 3103 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); 3104 } 3105 #endif 3106 supportNew[0] = (c - cStart)*8 + 3; 3107 supportNew[1] = (c - cStart)*8 + 3+4; 3108 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3109 #if 1 3110 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3111 for (p = 0; p < 2; ++p) { 3112 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); 3113 } 3114 #endif 3115 ++newp; 3116 /* Face E: {d, f, a} */ 3117 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3118 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3119 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3120 orntNew[1] = -2; 3121 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3122 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3123 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3124 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3125 #if 1 3126 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3127 for (p = 0; p < 3; ++p) { 3128 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); 3129 } 3130 #endif 3131 supportNew[0] = (c - cStart)*8 + 0+4; 3132 supportNew[1] = (c - cStart)*8 + 3+4; 3133 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3134 #if 1 3135 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3136 for (p = 0; p < 2; ++p) { 3137 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); 3138 } 3139 #endif 3140 ++newp; 3141 /* Face F: {c, a, f} */ 3142 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3143 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3144 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3145 orntNew[1] = 0; 3146 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3147 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3148 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3149 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3150 #if 1 3151 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3152 for (p = 0; p < 3; ++p) { 3153 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); 3154 } 3155 #endif 3156 supportNew[0] = (c - cStart)*8 + 0+4; 3157 supportNew[1] = (c - cStart)*8 + 2+4; 3158 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3159 #if 1 3160 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3161 for (p = 0; p < 2; ++p) { 3162 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); 3163 } 3164 #endif 3165 ++newp; 3166 /* Face G: {e, a, f} */ 3167 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3168 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3169 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3170 orntNew[1] = 0; 3171 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3172 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3173 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3174 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3175 #if 1 3176 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3177 for (p = 0; p < 3; ++p) { 3178 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); 3179 } 3180 #endif 3181 supportNew[0] = (c - cStart)*8 + 1+4; 3182 supportNew[1] = (c - cStart)*8 + 3+4; 3183 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3184 #if 1 3185 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3186 for (p = 0; p < 2; ++p) { 3187 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); 3188 } 3189 #endif 3190 ++newp; 3191 /* Face H: {a, b, f} */ 3192 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3193 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3194 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3195 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3196 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3197 orntNew[2] = -2; 3198 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3199 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3200 #if 1 3201 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3202 for (p = 0; p < 3; ++p) { 3203 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); 3204 } 3205 #endif 3206 supportNew[0] = (c - cStart)*8 + 1+4; 3207 supportNew[1] = (c - cStart)*8 + 2+4; 3208 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3209 #if 1 3210 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3211 for (p = 0; p < 2; ++p) { 3212 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); 3213 } 3214 #endif 3215 ++newp; 3216 } 3217 /* Split Edges have 2 vertices and the same faces as the parent */ 3218 for (e = eStart; e < eEnd; ++e) { 3219 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3220 3221 for (r = 0; r < 2; ++r) { 3222 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3223 const PetscInt *cone, *ornt, *support; 3224 PetscInt coneNew[2], coneSize, c, supportSize, s; 3225 3226 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3227 coneNew[0] = vStartNew + (cone[0] - vStart); 3228 coneNew[1] = vStartNew + (cone[1] - vStart); 3229 coneNew[(r+1)%2] = newv; 3230 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3231 #if 1 3232 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3233 for (p = 0; p < 2; ++p) { 3234 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); 3235 } 3236 #endif 3237 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3238 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3239 for (s = 0; s < supportSize; ++s) { 3240 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3241 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3242 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3243 for (c = 0; c < coneSize; ++c) { 3244 if (cone[c] == e) break; 3245 } 3246 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3247 } 3248 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3249 #if 1 3250 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3251 for (p = 0; p < supportSize; ++p) { 3252 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); 3253 } 3254 #endif 3255 } 3256 } 3257 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3258 for (f = fStart; f < fEnd; ++f) { 3259 const PetscInt *cone, *ornt, *support; 3260 PetscInt coneSize, supportSize, s; 3261 3262 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3263 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3264 for (r = 0; r < 3; ++r) { 3265 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3266 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3267 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3268 -1, -1, 1, 6, 0, 4, 3269 2, 5, 3, 4, -1, -1, 3270 -1, -1, 3, 6, 2, 7}; 3271 3272 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3273 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3274 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3275 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3276 #if 1 3277 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3278 for (p = 0; p < 2; ++p) { 3279 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); 3280 } 3281 #endif 3282 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3283 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3284 for (s = 0; s < supportSize; ++s) { 3285 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3286 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3287 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3288 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3289 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3290 er = GetTriMidEdgeInverse_Static(ornt[c], r); 3291 if (er == eint[c]) { 3292 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3293 } else { 3294 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3295 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3296 } 3297 } 3298 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3299 #if 1 3300 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3301 for (p = 0; p < intFaces; ++p) { 3302 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); 3303 } 3304 #endif 3305 } 3306 } 3307 /* Interior edges have 2 vertices and 4 faces */ 3308 for (c = cStart; c < cEnd; ++c) { 3309 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3310 const PetscInt *cone, *ornt, *fcone; 3311 PetscInt coneNew[2], supportNew[4], find; 3312 3313 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3314 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3315 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3316 find = GetTriEdge_Static(ornt[0], 0); 3317 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3318 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3319 find = GetTriEdge_Static(ornt[2], 1); 3320 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3321 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3322 #if 1 3323 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3324 for (p = 0; p < 2; ++p) { 3325 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); 3326 } 3327 #endif 3328 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3329 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3330 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3331 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3332 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3333 #if 1 3334 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3335 for (p = 0; p < 4; ++p) { 3336 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); 3337 } 3338 #endif 3339 } 3340 /* Old vertices have identical supports */ 3341 for (v = vStart; v < vEnd; ++v) { 3342 const PetscInt newp = vStartNew + (v - vStart); 3343 const PetscInt *support, *cone; 3344 PetscInt size, s; 3345 3346 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3347 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3348 for (s = 0; s < size; ++s) { 3349 PetscInt r = 0; 3350 3351 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3352 if (cone[1] == v) r = 1; 3353 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3354 } 3355 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3356 #if 1 3357 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3358 for (p = 0; p < size; ++p) { 3359 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); 3360 } 3361 #endif 3362 } 3363 /* Edge vertices have 2 + face*2 + 0/1 supports */ 3364 for (e = eStart; e < eEnd; ++e) { 3365 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3366 const PetscInt *cone, *support; 3367 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 3368 3369 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3370 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3371 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3372 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3373 for (s = 0; s < size; ++s) { 3374 PetscInt r = 0; 3375 3376 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3377 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3378 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3379 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3380 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3381 } 3382 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3383 for (s = 0; s < starSize*2; s += 2) { 3384 const PetscInt *cone, *ornt; 3385 PetscInt e01, e23; 3386 3387 if ((star[s] >= cStart) && (star[s] < cEnd)) { 3388 /* Check edge 0-1 */ 3389 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3390 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3391 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3392 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3393 /* Check edge 2-3 */ 3394 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3395 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3396 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3397 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3398 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 3399 } 3400 } 3401 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3402 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3403 #if 1 3404 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3405 for (p = 0; p < 2+size*2+cellSize; ++p) { 3406 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); 3407 } 3408 #endif 3409 } 3410 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3411 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 3412 break; 3413 case REFINER_HYBRID_SIMPLEX_3D: 3414 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 3415 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3416 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3417 for (c = cStart; c < cMax; ++c) { 3418 const PetscInt newp = cStartNew + (c - cStart)*8; 3419 const PetscInt *cone, *ornt; 3420 PetscInt coneNew[4], orntNew[4]; 3421 3422 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3423 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3424 /* A tetrahedron: {0, a, c, d} */ 3425 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3426 orntNew[0] = ornt[0]; 3427 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3428 orntNew[1] = ornt[1]; 3429 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3430 orntNew[2] = ornt[2]; 3431 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3432 orntNew[3] = 0; 3433 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3434 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3435 #if 1 3436 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); 3437 for (p = 0; p < 4; ++p) { 3438 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); 3439 } 3440 #endif 3441 /* B tetrahedron: {a, 1, b, e} */ 3442 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3443 orntNew[0] = ornt[0]; 3444 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3445 orntNew[1] = ornt[1]; 3446 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3447 orntNew[2] = 0; 3448 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3449 orntNew[3] = ornt[3]; 3450 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3451 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3452 #if 1 3453 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); 3454 for (p = 0; p < 4; ++p) { 3455 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); 3456 } 3457 #endif 3458 /* C tetrahedron: {c, b, 2, f} */ 3459 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3460 orntNew[0] = ornt[0]; 3461 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3462 orntNew[1] = 0; 3463 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3464 orntNew[2] = ornt[2]; 3465 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3466 orntNew[3] = ornt[3]; 3467 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3468 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3469 #if 1 3470 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); 3471 for (p = 0; p < 4; ++p) { 3472 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); 3473 } 3474 #endif 3475 /* D tetrahedron: {d, e, f, 3} */ 3476 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3477 orntNew[0] = 0; 3478 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3479 orntNew[1] = ornt[1]; 3480 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3481 orntNew[2] = ornt[2]; 3482 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3483 orntNew[3] = ornt[3]; 3484 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3485 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3486 #if 1 3487 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); 3488 for (p = 0; p < 4; ++p) { 3489 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); 3490 } 3491 #endif 3492 /* A' tetrahedron: {d, a, c, f} */ 3493 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 3494 orntNew[0] = -3; 3495 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3496 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3497 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3498 orntNew[2] = 0; 3499 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3500 orntNew[3] = 2; 3501 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3502 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3503 #if 1 3504 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); 3505 for (p = 0; p < 4; ++p) { 3506 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); 3507 } 3508 #endif 3509 /* B' tetrahedron: {e, b, a, f} */ 3510 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 3511 orntNew[0] = -3; 3512 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3513 orntNew[1] = 1; 3514 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3515 orntNew[2] = 0; 3516 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 3517 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 3518 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3519 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3520 #if 1 3521 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); 3522 for (p = 0; p < 4; ++p) { 3523 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); 3524 } 3525 #endif 3526 /* C' tetrahedron: {b, f, c, a} */ 3527 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 3528 orntNew[0] = -3; 3529 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 3530 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3531 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 3532 orntNew[2] = -3; 3533 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 3534 orntNew[3] = -2; 3535 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3536 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3537 #if 1 3538 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); 3539 for (p = 0; p < 4; ++p) { 3540 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); 3541 } 3542 #endif 3543 /* D' tetrahedron: {f, e, d, a} */ 3544 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 3545 orntNew[0] = -3; 3546 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 3547 orntNew[1] = -3; 3548 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 3549 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 3550 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 3551 orntNew[3] = -3; 3552 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3553 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3554 #if 1 3555 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); 3556 for (p = 0; p < 4; ++p) { 3557 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); 3558 } 3559 #endif 3560 } 3561 /* Hybrid cells have 5 faces */ 3562 for (c = cMax; c < cEnd; ++c) { 3563 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 3564 const PetscInt *cone, *ornt, *fornt; 3565 PetscInt coneNew[5], orntNew[5], o, of, i; 3566 3567 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3568 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3569 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 3570 o = ornt[0] < 0 ? -1 : 1; 3571 for (r = 0; r < 3; ++r) { 3572 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 3573 orntNew[0] = ornt[0]; 3574 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 3575 orntNew[1] = ornt[1]; 3576 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 3577 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 3578 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 3579 orntNew[i] = 0; 3580 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 3581 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 3582 orntNew[i] = 0; 3583 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 3584 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 3585 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); 3586 orntNew[i] = 0; 3587 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 3588 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 3589 #if 1 3590 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); 3591 for (p = 0; p < 2; ++p) { 3592 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); 3593 } 3594 for (p = 2; p < 5; ++p) { 3595 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); 3596 } 3597 #endif 3598 } 3599 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 3600 orntNew[0] = 0; 3601 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 3602 orntNew[1] = 0; 3603 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 3604 orntNew[2] = 0; 3605 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 3606 orntNew[3] = 0; 3607 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 3608 orntNew[4] = 0; 3609 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3610 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3611 #if 1 3612 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); 3613 for (p = 0; p < 2; ++p) { 3614 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); 3615 } 3616 for (p = 2; p < 5; ++p) { 3617 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); 3618 } 3619 #endif 3620 } 3621 /* Split faces have 3 edges and the same cells as the parent */ 3622 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3623 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3624 for (f = fStart; f < fMax; ++f) { 3625 const PetscInt newp = fStartNew + (f - fStart)*4; 3626 const PetscInt *cone, *ornt, *support; 3627 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3628 3629 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3630 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3631 /* A triangle */ 3632 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3633 orntNew[0] = ornt[0]; 3634 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3635 orntNew[1] = -2; 3636 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3637 orntNew[2] = ornt[2]; 3638 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3639 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3640 #if 1 3641 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); 3642 for (p = 0; p < 3; ++p) { 3643 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); 3644 } 3645 #endif 3646 /* B triangle */ 3647 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3648 orntNew[0] = ornt[0]; 3649 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3650 orntNew[1] = ornt[1]; 3651 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3652 orntNew[2] = -2; 3653 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3654 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3655 #if 1 3656 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); 3657 for (p = 0; p < 3; ++p) { 3658 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); 3659 } 3660 #endif 3661 /* C triangle */ 3662 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3663 orntNew[0] = -2; 3664 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3665 orntNew[1] = ornt[1]; 3666 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3667 orntNew[2] = ornt[2]; 3668 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3669 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3670 #if 1 3671 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); 3672 for (p = 0; p < 3; ++p) { 3673 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); 3674 } 3675 #endif 3676 /* D triangle */ 3677 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 3678 orntNew[0] = 0; 3679 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 3680 orntNew[1] = 0; 3681 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 3682 orntNew[2] = 0; 3683 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3684 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3685 #if 1 3686 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); 3687 for (p = 0; p < 3; ++p) { 3688 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); 3689 } 3690 #endif 3691 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3692 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3693 for (r = 0; r < 4; ++r) { 3694 for (s = 0; s < supportSize; ++s) { 3695 PetscInt subf; 3696 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3697 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3698 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3699 for (c = 0; c < coneSize; ++c) { 3700 if (cone[c] == f) break; 3701 } 3702 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3703 if (support[s] < cMax) { 3704 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3705 } else { 3706 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 3707 } 3708 } 3709 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3710 #if 1 3711 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); 3712 for (p = 0; p < supportSize; ++p) { 3713 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); 3714 } 3715 #endif 3716 } 3717 } 3718 /* Interior cell faces have 3 edges and 2 cells */ 3719 for (c = cStart; c < cMax; ++c) { 3720 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 3721 const PetscInt *cone, *ornt; 3722 PetscInt coneNew[3], orntNew[3]; 3723 PetscInt supportNew[2]; 3724 3725 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3726 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3727 /* Face A: {c, a, d} */ 3728 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3729 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3730 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3731 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3732 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3733 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3734 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3735 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3736 #if 1 3737 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3738 for (p = 0; p < 3; ++p) { 3739 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); 3740 } 3741 #endif 3742 supportNew[0] = (c - cStart)*8 + 0; 3743 supportNew[1] = (c - cStart)*8 + 0+4; 3744 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3745 #if 1 3746 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3747 for (p = 0; p < 2; ++p) { 3748 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); 3749 } 3750 #endif 3751 ++newp; 3752 /* Face B: {a, b, e} */ 3753 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3754 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3755 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3756 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3757 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3758 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3759 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3760 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3761 #if 1 3762 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); 3763 for (p = 0; p < 3; ++p) { 3764 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); 3765 } 3766 #endif 3767 supportNew[0] = (c - cStart)*8 + 1; 3768 supportNew[1] = (c - cStart)*8 + 1+4; 3769 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3770 #if 1 3771 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3772 for (p = 0; p < 2; ++p) { 3773 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); 3774 } 3775 #endif 3776 ++newp; 3777 /* Face C: {c, f, b} */ 3778 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3779 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3780 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3781 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3782 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3783 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3784 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3785 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3786 #if 1 3787 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3788 for (p = 0; p < 3; ++p) { 3789 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); 3790 } 3791 #endif 3792 supportNew[0] = (c - cStart)*8 + 2; 3793 supportNew[1] = (c - cStart)*8 + 2+4; 3794 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3795 #if 1 3796 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3797 for (p = 0; p < 2; ++p) { 3798 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); 3799 } 3800 #endif 3801 ++newp; 3802 /* Face D: {d, e, f} */ 3803 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3804 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3805 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3806 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3807 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3808 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3809 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3810 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3811 #if 1 3812 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3813 for (p = 0; p < 3; ++p) { 3814 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); 3815 } 3816 #endif 3817 supportNew[0] = (c - cStart)*8 + 3; 3818 supportNew[1] = (c - cStart)*8 + 3+4; 3819 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3820 #if 1 3821 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3822 for (p = 0; p < 2; ++p) { 3823 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); 3824 } 3825 #endif 3826 ++newp; 3827 /* Face E: {d, f, a} */ 3828 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3829 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3830 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3831 orntNew[1] = -2; 3832 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3833 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3834 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3835 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3836 #if 1 3837 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3838 for (p = 0; p < 3; ++p) { 3839 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); 3840 } 3841 #endif 3842 supportNew[0] = (c - cStart)*8 + 0+4; 3843 supportNew[1] = (c - cStart)*8 + 3+4; 3844 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3845 #if 1 3846 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3847 for (p = 0; p < 2; ++p) { 3848 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); 3849 } 3850 #endif 3851 ++newp; 3852 /* Face F: {c, a, f} */ 3853 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3854 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3855 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3856 orntNew[1] = 0; 3857 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3858 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3859 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3860 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3861 #if 1 3862 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3863 for (p = 0; p < 3; ++p) { 3864 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); 3865 } 3866 #endif 3867 supportNew[0] = (c - cStart)*8 + 0+4; 3868 supportNew[1] = (c - cStart)*8 + 2+4; 3869 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3870 #if 1 3871 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3872 for (p = 0; p < 2; ++p) { 3873 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); 3874 } 3875 #endif 3876 ++newp; 3877 /* Face G: {e, a, f} */ 3878 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3879 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3880 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3881 orntNew[1] = 0; 3882 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3883 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3884 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3885 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3886 #if 1 3887 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3888 for (p = 0; p < 3; ++p) { 3889 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); 3890 } 3891 #endif 3892 supportNew[0] = (c - cStart)*8 + 1+4; 3893 supportNew[1] = (c - cStart)*8 + 3+4; 3894 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3895 #if 1 3896 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3897 for (p = 0; p < 2; ++p) { 3898 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); 3899 } 3900 #endif 3901 ++newp; 3902 /* Face H: {a, b, f} */ 3903 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3904 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3905 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3906 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3907 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 3908 orntNew[2] = -2; 3909 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3910 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3911 #if 1 3912 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3913 for (p = 0; p < 3; ++p) { 3914 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); 3915 } 3916 #endif 3917 supportNew[0] = (c - cStart)*8 + 1+4; 3918 supportNew[1] = (c - cStart)*8 + 2+4; 3919 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3920 #if 1 3921 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 3922 for (p = 0; p < 2; ++p) { 3923 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); 3924 } 3925 #endif 3926 ++newp; 3927 } 3928 /* Hybrid split faces have 4 edges and same cells */ 3929 for (f = fMax; f < fEnd; ++f) { 3930 const PetscInt *cone, *ornt, *support; 3931 PetscInt coneNew[4], orntNew[4]; 3932 PetscInt supportNew[2], size, s, c; 3933 3934 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3935 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3936 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3937 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3938 for (r = 0; r < 2; ++r) { 3939 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 3940 3941 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 3942 orntNew[0] = ornt[0]; 3943 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 3944 orntNew[1] = ornt[1]; 3945 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 3946 orntNew[2+r] = 0; 3947 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 3948 orntNew[3-r] = 0; 3949 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3950 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3951 #if 1 3952 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3953 for (p = 0; p < 2; ++p) { 3954 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); 3955 } 3956 for (p = 2; p < 4; ++p) { 3957 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); 3958 } 3959 #endif 3960 for (s = 0; s < size; ++s) { 3961 const PetscInt *coneCell, *orntCell, *fornt; 3962 PetscInt o, of; 3963 3964 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 3965 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 3966 o = orntCell[0] < 0 ? -1 : 1; 3967 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 3968 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 3969 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 3970 of = fornt[c-2] < 0 ? -1 : 1; 3971 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 3972 } 3973 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3974 #if 1 3975 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 3976 for (p = 0; p < size; ++p) { 3977 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); 3978 } 3979 #endif 3980 } 3981 } 3982 /* Hybrid cell faces have 4 edges and 2 cells */ 3983 for (c = cMax; c < cEnd; ++c) { 3984 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 3985 const PetscInt *cone, *ornt; 3986 PetscInt coneNew[4], orntNew[4]; 3987 PetscInt supportNew[2]; 3988 3989 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3990 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3991 for (r = 0; r < 3; ++r) { 3992 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 3993 orntNew[0] = 0; 3994 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 3995 orntNew[1] = 0; 3996 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 3997 orntNew[2] = 0; 3998 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 3999 orntNew[3] = 0; 4000 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4001 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4002 #if 1 4003 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); 4004 for (p = 0; p < 2; ++p) { 4005 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); 4006 } 4007 for (p = 2; p < 4; ++p) { 4008 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); 4009 } 4010 #endif 4011 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 4012 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 4013 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4014 #if 1 4015 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); 4016 for (p = 0; p < 2; ++p) { 4017 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); 4018 } 4019 #endif 4020 } 4021 } 4022 /* Interior split edges have 2 vertices and the same faces as the parent */ 4023 for (e = eStart; e < eMax; ++e) { 4024 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4025 4026 for (r = 0; r < 2; ++r) { 4027 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4028 const PetscInt *cone, *ornt, *support; 4029 PetscInt coneNew[2], coneSize, c, supportSize, s; 4030 4031 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4032 coneNew[0] = vStartNew + (cone[0] - vStart); 4033 coneNew[1] = vStartNew + (cone[1] - vStart); 4034 coneNew[(r+1)%2] = newv; 4035 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4036 #if 1 4037 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4038 for (p = 0; p < 2; ++p) { 4039 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); 4040 } 4041 #endif 4042 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4043 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4044 for (s = 0; s < supportSize; ++s) { 4045 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4046 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4047 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4048 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 4049 if (support[s] < fMax) { 4050 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4051 } else { 4052 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4053 } 4054 } 4055 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4056 #if 1 4057 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4058 for (p = 0; p < supportSize; ++p) { 4059 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); 4060 } 4061 #endif 4062 } 4063 } 4064 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 4065 for (f = fStart; f < fMax; ++f) { 4066 const PetscInt *cone, *ornt, *support; 4067 PetscInt coneSize, supportSize, s; 4068 4069 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4070 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4071 for (r = 0; r < 3; ++r) { 4072 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 4073 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 4074 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 4075 -1, -1, 1, 6, 0, 4, 4076 2, 5, 3, 4, -1, -1, 4077 -1, -1, 3, 6, 2, 7}; 4078 4079 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4080 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4081 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4082 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4083 #if 1 4084 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4085 for (p = 0; p < 2; ++p) { 4086 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); 4087 } 4088 #endif 4089 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4090 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4091 for (s = 0; s < supportSize; ++s) { 4092 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4093 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4094 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4095 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4096 if (support[s] < cMax) { 4097 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4098 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4099 if (er == eint[c]) { 4100 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4101 } else { 4102 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4103 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4104 } 4105 } else { 4106 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4107 } 4108 } 4109 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4110 #if 1 4111 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4112 for (p = 0; p < intFaces; ++p) { 4113 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); 4114 } 4115 #endif 4116 } 4117 } 4118 /* Interior cell edges have 2 vertices and 4 faces */ 4119 for (c = cStart; c < cMax; ++c) { 4120 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4121 const PetscInt *cone, *ornt, *fcone; 4122 PetscInt coneNew[2], supportNew[4], find; 4123 4124 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4125 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4126 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4127 find = GetTriEdge_Static(ornt[0], 0); 4128 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4129 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4130 find = GetTriEdge_Static(ornt[2], 1); 4131 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4132 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4133 #if 1 4134 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4135 for (p = 0; p < 2; ++p) { 4136 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); 4137 } 4138 #endif 4139 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4140 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4141 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4142 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4143 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4144 #if 1 4145 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4146 for (p = 0; p < 4; ++p) { 4147 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); 4148 } 4149 #endif 4150 } 4151 /* Hybrid edges have two vertices and the same faces */ 4152 for (e = eMax; e < eEnd; ++e) { 4153 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4154 const PetscInt *cone, *support, *fcone; 4155 PetscInt coneNew[2], size, fsize, s; 4156 4157 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4158 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4159 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4160 coneNew[0] = vStartNew + (cone[0] - vStart); 4161 coneNew[1] = vStartNew + (cone[1] - vStart); 4162 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4163 #if 1 4164 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4165 for (p = 0; p < 2; ++p) { 4166 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); 4167 } 4168 #endif 4169 for (s = 0; s < size; ++s) { 4170 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4171 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4172 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4173 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 4174 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4175 } 4176 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4177 #if 1 4178 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4179 for (p = 0; p < size; ++p) { 4180 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); 4181 } 4182 #endif 4183 } 4184 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4185 for (f = fMax; f < fEnd; ++f) { 4186 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4187 const PetscInt *cone, *support, *ccone, *cornt; 4188 PetscInt coneNew[2], size, csize, s; 4189 4190 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4191 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4192 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4193 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4194 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4195 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4196 #if 1 4197 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4198 for (p = 0; p < 2; ++p) { 4199 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); 4200 } 4201 #endif 4202 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4203 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4204 for (s = 0; s < size; ++s) { 4205 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4206 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4207 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4208 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4209 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]); 4210 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4211 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4212 } 4213 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4214 #if 1 4215 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4216 for (p = 0; p < 2+size*2; ++p) { 4217 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); 4218 } 4219 #endif 4220 } 4221 /* Interior vertices have identical supports */ 4222 for (v = vStart; v < vEnd; ++v) { 4223 const PetscInt newp = vStartNew + (v - vStart); 4224 const PetscInt *support, *cone; 4225 PetscInt size, s; 4226 4227 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4228 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4229 for (s = 0; s < size; ++s) { 4230 PetscInt r = 0; 4231 4232 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4233 if (cone[1] == v) r = 1; 4234 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4235 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4236 } 4237 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4238 #if 1 4239 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4240 for (p = 0; p < size; ++p) { 4241 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); 4242 } 4243 #endif 4244 } 4245 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4246 for (e = eStart; e < eMax; ++e) { 4247 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4248 const PetscInt *cone, *support; 4249 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4250 4251 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4252 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4253 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4254 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4255 for (s = 0; s < size; ++s) { 4256 PetscInt r = 0; 4257 4258 if (support[s] < fMax) { 4259 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4260 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4261 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4262 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4263 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4264 faceSize += 2; 4265 } else { 4266 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4267 ++faceSize; 4268 } 4269 } 4270 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4271 for (s = 0; s < starSize*2; s += 2) { 4272 const PetscInt *cone, *ornt; 4273 PetscInt e01, e23; 4274 4275 if ((star[s] >= cStart) && (star[s] < cMax)) { 4276 /* Check edge 0-1 */ 4277 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4278 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4279 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4280 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4281 /* Check edge 2-3 */ 4282 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4283 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4284 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4285 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4286 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 4287 } 4288 } 4289 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4290 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4291 #if 1 4292 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4293 for (p = 0; p < 2+faceSize+cellSize; ++p) { 4294 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); 4295 } 4296 #endif 4297 } 4298 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4299 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4300 break; 4301 case REFINER_SIMPLEX_TO_HEX_3D: 4302 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4303 /* All cells have 6 faces */ 4304 for (c = cStart; c < cEnd; ++c) { 4305 const PetscInt newp = cStartNew + (c - cStart)*4; 4306 const PetscInt *cone, *ornt; 4307 PetscInt coneNew[6]; 4308 PetscInt orntNew[6]; 4309 4310 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4311 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4312 /* A hex */ 4313 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 4314 orntNew[0] = ornt[0] < 0 ? -1 : 1; 4315 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 4316 orntNew[1] = -4; 4317 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 4318 orntNew[2] = ornt[2] < 0 ? -1 : 1; 4319 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 4320 orntNew[3] = -1; 4321 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 4322 orntNew[4] = 0; 4323 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 4324 orntNew[5] = ornt[1] < 0 ? -1 : 1; 4325 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4326 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4327 #if 1 4328 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); 4329 for (p = 0; p < 6; ++p) { 4330 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); 4331 } 4332 #endif 4333 /* B hex */ 4334 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 4335 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4336 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 4337 orntNew[1] = 0; 4338 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 4339 orntNew[2] = 0; 4340 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 4341 orntNew[3] = ornt[3] < 0 ? -2 : 0; 4342 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 4343 orntNew[4] = 0; 4344 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 4345 orntNew[5] = ornt[1] < 0 ? -4 : 2; 4346 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4347 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4348 #if 1 4349 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); 4350 for (p = 0; p < 6; ++p) { 4351 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); 4352 } 4353 #endif 4354 /* C hex */ 4355 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 4356 orntNew[0] = ornt[0] < 0 ? -4 : 2; 4357 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 4358 orntNew[1] = -4; 4359 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 4360 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4361 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 4362 orntNew[3] = -1; 4363 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 4364 orntNew[4] = ornt[3] < 0 ? -1 : 1; 4365 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 4366 orntNew[5] = -4; 4367 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4368 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4369 #if 1 4370 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); 4371 for (p = 0; p < 6; ++p) { 4372 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); 4373 } 4374 #endif 4375 /* D hex */ 4376 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 4377 orntNew[0] = 0; 4378 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 4379 orntNew[1] = ornt[3] < 0 ? -1 : 1; 4380 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 4381 orntNew[2] = ornt[2] < 0 ? -4 : 2; 4382 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 4383 orntNew[3] = -1; 4384 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 4385 orntNew[4] = 0; 4386 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 4387 orntNew[5] = ornt[1] < 0 ? -2 : 0; 4388 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4389 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4390 #if 1 4391 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); 4392 for (p = 0; p < 6; ++p) { 4393 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); 4394 } 4395 #endif 4396 } 4397 /* Split faces have 4 edges and the same cells as the parent */ 4398 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4399 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4400 for (f = fStart; f < fEnd; ++f) { 4401 const PetscInt newp = fStartNew + (f - fStart)*3; 4402 const PetscInt *cone, *ornt, *support; 4403 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 4404 4405 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4406 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4407 /* A quad */ 4408 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4409 orntNew[0] = ornt[2]; 4410 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4411 orntNew[1] = ornt[0]; 4412 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4413 orntNew[2] = 0; 4414 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4415 orntNew[3] = -2; 4416 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4417 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4418 #if 1 4419 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); 4420 for (p = 0; p < 4; ++p) { 4421 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); 4422 } 4423 #endif 4424 /* B quad */ 4425 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4426 orntNew[0] = ornt[0]; 4427 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4428 orntNew[1] = ornt[1]; 4429 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4430 orntNew[2] = 0; 4431 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4432 orntNew[3] = -2; 4433 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4434 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4435 #if 1 4436 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); 4437 for (p = 0; p < 4; ++p) { 4438 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); 4439 } 4440 #endif 4441 /* C quad */ 4442 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4443 orntNew[0] = ornt[1]; 4444 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4445 orntNew[1] = ornt[2]; 4446 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4447 orntNew[2] = 0; 4448 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4449 orntNew[3] = -2; 4450 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4451 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4452 #if 1 4453 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); 4454 for (p = 0; p < 4; ++p) { 4455 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); 4456 } 4457 #endif 4458 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4459 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4460 for (r = 0; r < 3; ++r) { 4461 for (s = 0; s < supportSize; ++s) { 4462 PetscInt subf; 4463 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4464 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4465 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4466 for (c = 0; c < coneSize; ++c) { 4467 if (cone[c] == f) break; 4468 } 4469 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4470 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 4471 } 4472 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4473 #if 1 4474 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); 4475 for (p = 0; p < supportSize; ++p) { 4476 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); 4477 } 4478 #endif 4479 } 4480 } 4481 /* Interior faces have 4 edges and 2 cells */ 4482 for (c = cStart; c < cEnd; ++c) { 4483 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 4484 const PetscInt *cone, *ornt; 4485 PetscInt coneNew[4], orntNew[4]; 4486 PetscInt supportNew[2]; 4487 4488 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4489 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4490 /* Face {a, g, m, h} */ 4491 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 4492 orntNew[0] = 0; 4493 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4494 orntNew[1] = 0; 4495 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4496 orntNew[2] = -2; 4497 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 4498 orntNew[3] = -2; 4499 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4500 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4501 #if 1 4502 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4503 for (p = 0; p < 4; ++p) { 4504 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); 4505 } 4506 #endif 4507 supportNew[0] = (c - cStart)*4 + 0; 4508 supportNew[1] = (c - cStart)*4 + 1; 4509 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4510 #if 1 4511 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4512 for (p = 0; p < 2; ++p) { 4513 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); 4514 } 4515 #endif 4516 ++newp; 4517 /* Face {g, b, l , m} */ 4518 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 4519 orntNew[0] = -2; 4520 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 4521 orntNew[1] = 0; 4522 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4523 orntNew[2] = 0; 4524 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4525 orntNew[3] = -2; 4526 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4527 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4528 #if 1 4529 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4530 for (p = 0; p < 4; ++p) { 4531 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); 4532 } 4533 #endif 4534 supportNew[0] = (c - cStart)*4 + 1; 4535 supportNew[1] = (c - cStart)*4 + 2; 4536 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4537 #if 1 4538 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4539 for (p = 0; p < 2; ++p) { 4540 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); 4541 } 4542 #endif 4543 ++newp; 4544 /* Face {c, g, m, i} */ 4545 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 4546 orntNew[0] = 0; 4547 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4548 orntNew[1] = 0; 4549 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4550 orntNew[2] = -2; 4551 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 4552 orntNew[3] = -2; 4553 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4554 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4555 #if 1 4556 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4557 for (p = 0; p < 4; ++p) { 4558 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); 4559 } 4560 #endif 4561 supportNew[0] = (c - cStart)*4 + 0; 4562 supportNew[1] = (c - cStart)*4 + 2; 4563 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4564 #if 1 4565 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4566 for (p = 0; p < 2; ++p) { 4567 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); 4568 } 4569 #endif 4570 ++newp; 4571 /* Face {d, h, m, i} */ 4572 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 4573 orntNew[0] = 0; 4574 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4575 orntNew[1] = 0; 4576 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4577 orntNew[2] = -2; 4578 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 4579 orntNew[3] = -2; 4580 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4581 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4582 #if 1 4583 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4584 for (p = 0; p < 4; ++p) { 4585 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); 4586 } 4587 #endif 4588 supportNew[0] = (c - cStart)*4 + 0; 4589 supportNew[1] = (c - cStart)*4 + 3; 4590 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4591 #if 1 4592 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4593 for (p = 0; p < 2; ++p) { 4594 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); 4595 } 4596 #endif 4597 ++newp; 4598 /* Face {h, m, l, e} */ 4599 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4600 orntNew[0] = 0; 4601 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4602 orntNew[1] = -2; 4603 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 4604 orntNew[2] = -2; 4605 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 4606 orntNew[3] = 0; 4607 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4608 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4609 #if 1 4610 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4611 for (p = 0; p < 4; ++p) { 4612 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); 4613 } 4614 #endif 4615 supportNew[0] = (c - cStart)*4 + 1; 4616 supportNew[1] = (c - cStart)*4 + 3; 4617 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4618 #if 1 4619 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4620 for (p = 0; p < 2; ++p) { 4621 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); 4622 } 4623 #endif 4624 ++newp; 4625 /* Face {i, m, l, f} */ 4626 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4627 orntNew[0] = 0; 4628 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4629 orntNew[1] = -2; 4630 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 4631 orntNew[2] = -2; 4632 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 4633 orntNew[3] = 0; 4634 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4635 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4636 #if 1 4637 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4638 for (p = 0; p < 4; ++p) { 4639 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); 4640 } 4641 #endif 4642 supportNew[0] = (c - cStart)*4 + 2; 4643 supportNew[1] = (c - cStart)*4 + 3; 4644 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4645 #if 1 4646 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 4647 for (p = 0; p < 2; ++p) { 4648 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); 4649 } 4650 #endif 4651 ++newp; 4652 } 4653 /* Split Edges have 2 vertices and the same faces as the parent */ 4654 for (e = eStart; e < eEnd; ++e) { 4655 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4656 4657 for (r = 0; r < 2; ++r) { 4658 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4659 const PetscInt *cone, *ornt, *support; 4660 PetscInt coneNew[2], coneSize, c, supportSize, s; 4661 4662 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4663 coneNew[0] = vStartNew + (cone[0] - vStart); 4664 coneNew[1] = vStartNew + (cone[1] - vStart); 4665 coneNew[(r+1)%2] = newv; 4666 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4667 #if 1 4668 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4669 for (p = 0; p < 2; ++p) { 4670 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); 4671 } 4672 #endif 4673 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4674 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4675 for (s = 0; s < supportSize; ++s) { 4676 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4677 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4678 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4679 for (c = 0; c < coneSize; ++c) { 4680 if (cone[c] == e) break; 4681 } 4682 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4683 } 4684 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4685 #if 1 4686 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4687 for (p = 0; p < supportSize; ++p) { 4688 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); 4689 } 4690 #endif 4691 } 4692 } 4693 /* Face edges have 2 vertices and 2 + cell faces supports */ 4694 for (f = fStart; f < fEnd; ++f) { 4695 const PetscInt *cone, *ornt, *support; 4696 PetscInt coneSize, supportSize, s; 4697 4698 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4699 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4700 for (r = 0; r < 3; ++r) { 4701 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 4702 PetscInt coneNew[2]; 4703 PetscInt fint[4][3] = { {0, 1, 2}, 4704 {3, 4, 0}, 4705 {2, 5, 3}, 4706 {1, 4, 5} }; 4707 4708 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4709 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 4710 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 4711 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4712 #if 1 4713 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4714 for (p = 0; p < 2; ++p) { 4715 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); 4716 } 4717 #endif 4718 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 4719 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 4720 for (s = 0; s < supportSize; ++s) { 4721 PetscInt er; 4722 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4723 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4724 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4725 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4726 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 4727 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 4728 } 4729 ierr = DMPlexSetSupport(rdm, newp, supportRef);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 < supportSize + 2; ++p) { 4733 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); 4734 } 4735 #endif 4736 } 4737 } 4738 /* Interior cell edges have 2 vertices and 3 faces */ 4739 for (c = cStart; c < cEnd; ++c) { 4740 const PetscInt *cone; 4741 PetscInt fint[4][3] = { {0,1,2}, 4742 {0,3,4}, 4743 {2,3,5}, 4744 {1,4,5} } ; 4745 4746 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4747 for (r = 0; r < 4; r++) { 4748 PetscInt coneNew[2], supportNew[3]; 4749 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 4750 4751 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 4752 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 4753 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4754 #if 1 4755 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4756 for (p = 0; p < 2; ++p) { 4757 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); 4758 } 4759 #endif 4760 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 4761 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 4762 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 4763 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4764 #if 1 4765 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 4766 for (p = 0; p < 3; ++p) { 4767 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); 4768 } 4769 #endif 4770 } 4771 } 4772 /* Old vertices have identical supports */ 4773 for (v = vStart; v < vEnd; ++v) { 4774 const PetscInt newp = vStartNew + (v - vStart); 4775 const PetscInt *support, *cone; 4776 PetscInt size, s; 4777 4778 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4779 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4780 for (s = 0; s < size; ++s) { 4781 PetscInt r = 0; 4782 4783 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4784 if (cone[1] == v) r = 1; 4785 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4786 } 4787 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4788 #if 1 4789 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4790 for (p = 0; p < size; ++p) { 4791 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); 4792 } 4793 #endif 4794 } 4795 /* Edge vertices have 2 + faces supports */ 4796 for (e = eStart; e < eEnd; ++e) { 4797 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4798 const PetscInt *cone, *support; 4799 PetscInt size, s; 4800 4801 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4802 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4803 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4804 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4805 for (s = 0; s < size; ++s) { 4806 PetscInt r = 0, coneSize; 4807 4808 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4809 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4810 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4811 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 4812 } 4813 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4814 #if 1 4815 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4816 for (p = 0; p < 2+size; ++p) { 4817 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); 4818 } 4819 #endif 4820 } 4821 /* Face vertices have 3 + cells supports */ 4822 for (f = fStart; f < fEnd; ++f) { 4823 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 4824 const PetscInt *cone, *support; 4825 PetscInt size, s; 4826 4827 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4828 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4829 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 4830 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 4831 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 4832 for (s = 0; s < size; ++s) { 4833 PetscInt r = 0, coneSize; 4834 4835 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4836 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4837 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 4838 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 4839 } 4840 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4841 #if 1 4842 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4843 for (p = 0; p < 3+size; ++p) { 4844 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); 4845 } 4846 #endif 4847 } 4848 /* Interior cell vertices have 4 supports */ 4849 for (c = cStart; c < cEnd; ++c) { 4850 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 4851 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 4852 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 4853 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 4854 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 4855 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4856 #if 1 4857 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4858 for (p = 0; p < 4; ++p) { 4859 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); 4860 } 4861 #endif 4862 } 4863 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4864 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4865 break; 4866 case REFINER_HEX_3D: 4867 /* 4868 Bottom (viewed from top) Top 4869 1---------2---------2 7---------2---------6 4870 | | | | | | 4871 | B 2 C | | H 2 G | 4872 | | | | | | 4873 3----3----0----1----1 3----3----0----1----1 4874 | | | | | | 4875 | A 0 D | | E 0 F | 4876 | | | | | | 4877 0---------0---------3 4---------0---------5 4878 */ 4879 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 4880 for (c = cStart; c < cEnd; ++c) { 4881 const PetscInt newp = (c - cStart)*8; 4882 const PetscInt *cone, *ornt; 4883 PetscInt coneNew[6], orntNew[6]; 4884 4885 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4886 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4887 /* A hex */ 4888 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 4889 orntNew[0] = ornt[0]; 4890 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4891 orntNew[1] = 0; 4892 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 4893 orntNew[2] = ornt[2]; 4894 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4895 orntNew[3] = 0; 4896 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4897 orntNew[4] = 0; 4898 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 4899 orntNew[5] = ornt[5]; 4900 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4901 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4902 #if 1 4903 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); 4904 for (p = 0; p < 6; ++p) { 4905 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); 4906 } 4907 #endif 4908 /* B hex */ 4909 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 4910 orntNew[0] = ornt[0]; 4911 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 4912 orntNew[1] = 0; 4913 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 4914 orntNew[2] = -1; 4915 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 4916 orntNew[3] = ornt[3]; 4917 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4918 orntNew[4] = 0; 4919 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 4920 orntNew[5] = ornt[5]; 4921 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4922 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4923 #if 1 4924 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); 4925 for (p = 0; p < 6; ++p) { 4926 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); 4927 } 4928 #endif 4929 /* C hex */ 4930 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 4931 orntNew[0] = ornt[0]; 4932 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 4933 orntNew[1] = 0; 4934 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4935 orntNew[2] = -1; 4936 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 4937 orntNew[3] = ornt[3]; 4938 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 4939 orntNew[4] = ornt[4]; 4940 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 4941 orntNew[5] = -4; 4942 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4943 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4944 #if 1 4945 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); 4946 for (p = 0; p < 6; ++p) { 4947 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); 4948 } 4949 #endif 4950 /* D hex */ 4951 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 4952 orntNew[0] = ornt[0]; 4953 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4954 orntNew[1] = 0; 4955 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 4956 orntNew[2] = ornt[2]; 4957 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 4958 orntNew[3] = 0; 4959 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 4960 orntNew[4] = ornt[4]; 4961 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 4962 orntNew[5] = -4; 4963 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4964 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4965 #if 1 4966 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); 4967 for (p = 0; p < 6; ++p) { 4968 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); 4969 } 4970 #endif 4971 /* E hex */ 4972 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 4973 orntNew[0] = -4; 4974 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 4975 orntNew[1] = ornt[1]; 4976 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 4977 orntNew[2] = ornt[2]; 4978 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 4979 orntNew[3] = 0; 4980 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 4981 orntNew[4] = -1; 4982 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 4983 orntNew[5] = ornt[5]; 4984 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4985 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4986 #if 1 4987 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); 4988 for (p = 0; p < 6; ++p) { 4989 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); 4990 } 4991 #endif 4992 /* F hex */ 4993 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 4994 orntNew[0] = -4; 4995 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 4996 orntNew[1] = ornt[1]; 4997 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 4998 orntNew[2] = ornt[2]; 4999 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5000 orntNew[3] = -1; 5001 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 5002 orntNew[4] = ornt[4]; 5003 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 5004 orntNew[5] = 1; 5005 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 5006 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 5007 #if 1 5008 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); 5009 for (p = 0; p < 6; ++p) { 5010 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); 5011 } 5012 #endif 5013 /* G hex */ 5014 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 5015 orntNew[0] = -4; 5016 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 5017 orntNew[1] = ornt[1]; 5018 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5019 orntNew[2] = 0; 5020 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 5021 orntNew[3] = ornt[3]; 5022 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 5023 orntNew[4] = ornt[4]; 5024 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5025 orntNew[5] = -3; 5026 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 5027 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 5028 #if 1 5029 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); 5030 for (p = 0; p < 6; ++p) { 5031 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); 5032 } 5033 #endif 5034 /* H hex */ 5035 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5036 orntNew[0] = -4; 5037 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 5038 orntNew[1] = ornt[1]; 5039 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5040 orntNew[2] = -1; 5041 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 5042 orntNew[3] = ornt[3]; 5043 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5044 orntNew[4] = 3; 5045 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 5046 orntNew[5] = ornt[5]; 5047 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 5048 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 5049 #if 1 5050 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); 5051 for (p = 0; p < 6; ++p) { 5052 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); 5053 } 5054 #endif 5055 } 5056 /* Split faces have 4 edges and the same cells as the parent */ 5057 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5058 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5059 for (f = fStart; f < fEnd; ++f) { 5060 for (r = 0; r < 4; ++r) { 5061 /* TODO: This can come from GetFaces_Internal() */ 5062 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}; 5063 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 5064 const PetscInt *cone, *ornt, *support; 5065 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 5066 5067 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5068 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5069 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 5070 orntNew[(r+3)%4] = ornt[(r+3)%4]; 5071 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 5072 orntNew[(r+0)%4] = ornt[r]; 5073 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5074 orntNew[(r+1)%4] = 0; 5075 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 5076 orntNew[(r+2)%4] = -2; 5077 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5078 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5079 #if 1 5080 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5081 for (p = 0; p < 4; ++p) { 5082 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); 5083 } 5084 #endif 5085 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5086 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5087 for (s = 0; s < supportSize; ++s) { 5088 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5089 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5090 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5091 for (c = 0; c < coneSize; ++c) { 5092 if (cone[c] == f) break; 5093 } 5094 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 5095 } 5096 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5097 #if 1 5098 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5099 for (p = 0; p < supportSize; ++p) { 5100 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); 5101 } 5102 #endif 5103 } 5104 } 5105 /* Interior faces have 4 edges and 2 cells */ 5106 for (c = cStart; c < cEnd; ++c) { 5107 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}; 5108 const PetscInt *cone, *ornt; 5109 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 5110 5111 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5112 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5113 /* A-D face */ 5114 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 5115 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 5116 orntNew[0] = 0; 5117 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5118 orntNew[1] = 0; 5119 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5120 orntNew[2] = -2; 5121 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 5122 orntNew[3] = -2; 5123 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5124 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5125 #if 1 5126 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5127 for (p = 0; p < 4; ++p) { 5128 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); 5129 } 5130 #endif 5131 /* C-D face */ 5132 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 5133 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 5134 orntNew[0] = 0; 5135 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5136 orntNew[1] = 0; 5137 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5138 orntNew[2] = -2; 5139 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 5140 orntNew[3] = -2; 5141 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5142 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5143 #if 1 5144 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5145 for (p = 0; p < 4; ++p) { 5146 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); 5147 } 5148 #endif 5149 /* B-C face */ 5150 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 5151 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 5152 orntNew[0] = -2; 5153 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 5154 orntNew[1] = 0; 5155 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5156 orntNew[2] = 0; 5157 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5158 orntNew[3] = -2; 5159 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5160 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5161 #if 1 5162 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5163 for (p = 0; p < 4; ++p) { 5164 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); 5165 } 5166 #endif 5167 /* A-B face */ 5168 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 5169 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 5170 orntNew[0] = -2; 5171 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 5172 orntNew[1] = 0; 5173 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5174 orntNew[2] = 0; 5175 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 5176 orntNew[3] = -2; 5177 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5178 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5179 #if 1 5180 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5181 for (p = 0; p < 4; ++p) { 5182 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); 5183 } 5184 #endif 5185 /* E-F face */ 5186 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 5187 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5188 orntNew[0] = -2; 5189 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 5190 orntNew[1] = -2; 5191 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 5192 orntNew[2] = 0; 5193 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5194 orntNew[3] = 0; 5195 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5196 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5197 #if 1 5198 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5199 for (p = 0; p < 4; ++p) { 5200 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); 5201 } 5202 #endif 5203 /* F-G face */ 5204 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 5205 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5206 orntNew[0] = -2; 5207 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 5208 orntNew[1] = -2; 5209 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 5210 orntNew[2] = 0; 5211 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5212 orntNew[3] = 0; 5213 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5214 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5215 #if 1 5216 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5217 for (p = 0; p < 4; ++p) { 5218 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); 5219 } 5220 #endif 5221 /* G-H face */ 5222 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 5223 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 5224 orntNew[0] = -2; 5225 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 5226 orntNew[1] = 0; 5227 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5228 orntNew[2] = 0; 5229 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5230 orntNew[3] = -2; 5231 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5232 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5233 #if 1 5234 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5235 for (p = 0; p < 4; ++p) { 5236 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); 5237 } 5238 #endif 5239 /* E-H face */ 5240 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 5241 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5242 orntNew[0] = -2; 5243 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 5244 orntNew[1] = -2; 5245 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 5246 orntNew[2] = 0; 5247 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 5248 orntNew[3] = 0; 5249 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5250 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5251 #if 1 5252 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5253 for (p = 0; p < 4; ++p) { 5254 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); 5255 } 5256 #endif 5257 /* A-E face */ 5258 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 5259 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 5260 orntNew[0] = 0; 5261 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5262 orntNew[1] = 0; 5263 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5264 orntNew[2] = -2; 5265 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 5266 orntNew[3] = -2; 5267 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5268 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5269 #if 1 5270 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5271 for (p = 0; p < 4; ++p) { 5272 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); 5273 } 5274 #endif 5275 /* D-F face */ 5276 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 5277 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 5278 orntNew[0] = -2; 5279 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 5280 orntNew[1] = 0; 5281 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5282 orntNew[2] = 0; 5283 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 5284 orntNew[3] = -2; 5285 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5286 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5287 #if 1 5288 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5289 for (p = 0; p < 4; ++p) { 5290 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); 5291 } 5292 #endif 5293 /* C-G face */ 5294 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 5295 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 5296 orntNew[0] = -2; 5297 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 5298 orntNew[1] = -2; 5299 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 5300 orntNew[2] = 0; 5301 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5302 orntNew[3] = 0; 5303 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5304 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5305 #if 1 5306 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5307 for (p = 0; p < 4; ++p) { 5308 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); 5309 } 5310 #endif 5311 /* B-H face */ 5312 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 5313 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 5314 orntNew[0] = 0; 5315 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 5316 orntNew[1] = -2; 5317 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 5318 orntNew[2] = -2; 5319 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 5320 orntNew[3] = 0; 5321 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5322 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5323 #if 1 5324 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5325 for (p = 0; p < 4; ++p) { 5326 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); 5327 } 5328 #endif 5329 for (r = 0; r < 12; ++r) { 5330 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 5331 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 5332 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 5333 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5334 #if 1 5335 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5336 for (p = 0; p < 2; ++p) { 5337 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); 5338 } 5339 #endif 5340 } 5341 } 5342 /* Split edges have 2 vertices and the same faces as the parent */ 5343 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5344 for (e = eStart; e < eEnd; ++e) { 5345 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5346 5347 for (r = 0; r < 2; ++r) { 5348 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5349 const PetscInt *cone, *ornt, *support; 5350 PetscInt coneNew[2], coneSize, c, supportSize, s; 5351 5352 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5353 coneNew[0] = vStartNew + (cone[0] - vStart); 5354 coneNew[1] = vStartNew + (cone[1] - vStart); 5355 coneNew[(r+1)%2] = newv; 5356 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5357 #if 1 5358 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5359 for (p = 0; p < 2; ++p) { 5360 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); 5361 } 5362 #endif 5363 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5364 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5365 for (s = 0; s < supportSize; ++s) { 5366 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5367 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5368 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5369 for (c = 0; c < coneSize; ++c) { 5370 if (cone[c] == e) break; 5371 } 5372 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 5373 } 5374 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5375 #if 1 5376 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5377 for (p = 0; p < supportSize; ++p) { 5378 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); 5379 } 5380 #endif 5381 } 5382 } 5383 /* Face edges have 2 vertices and 2+cells faces */ 5384 for (f = fStart; f < fEnd; ++f) { 5385 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}; 5386 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5387 const PetscInt *cone, *coneCell, *orntCell, *support; 5388 PetscInt coneNew[2], coneSize, c, supportSize, s; 5389 5390 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5391 for (r = 0; r < 4; ++r) { 5392 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5393 5394 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5395 coneNew[1] = newv; 5396 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5397 #if 1 5398 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5399 for (p = 0; p < 2; ++p) { 5400 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); 5401 } 5402 #endif 5403 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5404 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5405 supportRef[0] = fStartNew + (f - fStart)*4 + r; 5406 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 5407 for (s = 0; s < supportSize; ++s) { 5408 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5409 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5410 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5411 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5412 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 5413 } 5414 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5415 #if 1 5416 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5417 for (p = 0; p < 2+supportSize; ++p) { 5418 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); 5419 } 5420 #endif 5421 } 5422 } 5423 /* Cell edges have 2 vertices and 4 faces */ 5424 for (c = cStart; c < cEnd; ++c) { 5425 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}; 5426 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 5427 const PetscInt *cone; 5428 PetscInt coneNew[2], supportNew[4]; 5429 5430 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5431 for (r = 0; r < 6; ++r) { 5432 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 5433 5434 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5435 coneNew[1] = newv; 5436 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5437 #if 1 5438 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5439 for (p = 0; p < 2; ++p) { 5440 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); 5441 } 5442 #endif 5443 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 5444 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5445 #if 1 5446 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5447 for (p = 0; p < 4; ++p) { 5448 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); 5449 } 5450 #endif 5451 } 5452 } 5453 /* Old vertices have identical supports */ 5454 for (v = vStart; v < vEnd; ++v) { 5455 const PetscInt newp = vStartNew + (v - vStart); 5456 const PetscInt *support, *cone; 5457 PetscInt size, s; 5458 5459 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5460 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5461 for (s = 0; s < size; ++s) { 5462 PetscInt r = 0; 5463 5464 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5465 if (cone[1] == v) r = 1; 5466 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5467 } 5468 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5469 #if 1 5470 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5471 for (p = 0; p < size; ++p) { 5472 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); 5473 } 5474 #endif 5475 } 5476 /* Edge vertices have 2 + faces supports */ 5477 for (e = eStart; e < eEnd; ++e) { 5478 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5479 const PetscInt *cone, *support; 5480 PetscInt size, s; 5481 5482 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5483 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5484 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5485 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 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 < 4; ++r) if (cone[r] == e) break; 5491 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + 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 < 2+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 /* Face vertices have 4 + cells supports */ 5502 for (f = fStart; f < fEnd; ++f) { 5503 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5504 const PetscInt *cone, *support; 5505 PetscInt size, s; 5506 5507 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5508 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5509 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 5510 for (s = 0; s < size; ++s) { 5511 PetscInt r; 5512 5513 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5514 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 5515 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 5516 } 5517 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5518 #if 1 5519 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5520 for (p = 0; p < 4+size; ++p) { 5521 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); 5522 } 5523 #endif 5524 } 5525 /* Cell vertices have 6 supports */ 5526 for (c = cStart; c < cEnd; ++c) { 5527 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 5528 PetscInt supportNew[6]; 5529 5530 for (r = 0; r < 6; ++r) { 5531 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 5532 } 5533 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5534 } 5535 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5536 break; 5537 case REFINER_HYBRID_HEX_3D: 5538 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 5539 /* 5540 Bottom (viewed from top) Top 5541 1---------2---------2 7---------2---------6 5542 | | | | | | 5543 | B 2 C | | H 2 G | 5544 | | | | | | 5545 3----3----0----1----1 3----3----0----1----1 5546 | | | | | | 5547 | A 0 D | | E 0 F | 5548 | | | | | | 5549 0---------0---------3 4---------0---------5 5550 */ 5551 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 5552 for (c = cStart; c < cMax; ++c) { 5553 const PetscInt newp = (c - cStart)*8; 5554 const PetscInt *cone, *ornt; 5555 PetscInt coneNew[6], orntNew[6]; 5556 5557 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5558 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5559 /* A hex */ 5560 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 5561 orntNew[0] = ornt[0]; 5562 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 5563 orntNew[1] = 0; 5564 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 5565 orntNew[2] = ornt[2]; 5566 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 5567 orntNew[3] = 0; 5568 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 5569 orntNew[4] = 0; 5570 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 5571 orntNew[5] = ornt[5]; 5572 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5573 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5574 #if 1 5575 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); 5576 for (p = 0; p < 6; ++p) { 5577 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); 5578 } 5579 #endif 5580 /* B hex */ 5581 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 5582 orntNew[0] = ornt[0]; 5583 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5584 orntNew[1] = 0; 5585 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 5586 orntNew[2] = -1; 5587 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 5588 orntNew[3] = ornt[3]; 5589 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 5590 orntNew[4] = 0; 5591 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 5592 orntNew[5] = ornt[5]; 5593 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5594 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5595 #if 1 5596 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); 5597 for (p = 0; p < 6; ++p) { 5598 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); 5599 } 5600 #endif 5601 /* C hex */ 5602 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 5603 orntNew[0] = ornt[0]; 5604 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 5605 orntNew[1] = 0; 5606 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 5607 orntNew[2] = -1; 5608 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 5609 orntNew[3] = ornt[3]; 5610 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 5611 orntNew[4] = ornt[4]; 5612 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 5613 orntNew[5] = -4; 5614 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5615 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5616 #if 1 5617 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); 5618 for (p = 0; p < 6; ++p) { 5619 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); 5620 } 5621 #endif 5622 /* D hex */ 5623 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 5624 orntNew[0] = ornt[0]; 5625 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 5626 orntNew[1] = 0; 5627 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 5628 orntNew[2] = ornt[2]; 5629 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 5630 orntNew[3] = 0; 5631 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 5632 orntNew[4] = ornt[4]; 5633 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 5634 orntNew[5] = -4; 5635 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5636 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5637 #if 1 5638 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); 5639 for (p = 0; p < 6; ++p) { 5640 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); 5641 } 5642 #endif 5643 /* E hex */ 5644 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 5645 orntNew[0] = -4; 5646 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 5647 orntNew[1] = ornt[1]; 5648 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 5649 orntNew[2] = ornt[2]; 5650 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5651 orntNew[3] = 0; 5652 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 5653 orntNew[4] = -1; 5654 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 5655 orntNew[5] = ornt[5]; 5656 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 5657 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 5658 #if 1 5659 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); 5660 for (p = 0; p < 6; ++p) { 5661 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); 5662 } 5663 #endif 5664 /* F hex */ 5665 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 5666 orntNew[0] = -4; 5667 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 5668 orntNew[1] = ornt[1]; 5669 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 5670 orntNew[2] = ornt[2]; 5671 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5672 orntNew[3] = -1; 5673 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 5674 orntNew[4] = ornt[4]; 5675 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 5676 orntNew[5] = 1; 5677 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 5678 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 5679 #if 1 5680 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); 5681 for (p = 0; p < 6; ++p) { 5682 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); 5683 } 5684 #endif 5685 /* G hex */ 5686 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 5687 orntNew[0] = -4; 5688 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 5689 orntNew[1] = ornt[1]; 5690 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 5691 orntNew[2] = 0; 5692 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 5693 orntNew[3] = ornt[3]; 5694 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 5695 orntNew[4] = ornt[4]; 5696 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5697 orntNew[5] = -3; 5698 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 5699 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 5700 #if 1 5701 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); 5702 for (p = 0; p < 6; ++p) { 5703 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); 5704 } 5705 #endif 5706 /* H hex */ 5707 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 5708 orntNew[0] = -4; 5709 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 5710 orntNew[1] = ornt[1]; 5711 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 5712 orntNew[2] = -1; 5713 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 5714 orntNew[3] = ornt[3]; 5715 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 5716 orntNew[4] = 3; 5717 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 5718 orntNew[5] = ornt[5]; 5719 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 5720 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 5721 #if 1 5722 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); 5723 for (p = 0; p < 6; ++p) { 5724 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); 5725 } 5726 #endif 5727 } 5728 /* Hybrid cells have 6 faces: Front, Back, Sides */ 5729 /* 5730 3---------2---------2 5731 | | | 5732 | D 2 C | 5733 | | | 5734 3----3----0----1----1 5735 | | | 5736 | A 0 B | 5737 | | | 5738 0---------0---------1 5739 */ 5740 for (c = cMax; c < cEnd; ++c) { 5741 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 5742 const PetscInt *cone, *ornt, *fornt; 5743 PetscInt coneNew[6], orntNew[6], o, of, i; 5744 5745 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5746 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5747 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 5748 o = ornt[0] < 0 ? -1 : 1; 5749 for (r = 0; r < 4; ++r) { 5750 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 5751 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 5752 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 5753 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]); 5754 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 5755 orntNew[0] = ornt[0]; 5756 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 5757 orntNew[1] = ornt[0]; 5758 of = fornt[edgeA] < 0 ? -1 : 1; 5759 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 5760 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 5761 orntNew[i] = ornt[edgeA]; 5762 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 5763 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 5764 orntNew[i] = 0; 5765 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 5766 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 5767 orntNew[i] = -2; 5768 of = fornt[edgeB] < 0 ? -1 : 1; 5769 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 5770 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 5771 orntNew[i] = ornt[edgeB]; 5772 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 5773 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 5774 #if 1 5775 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); 5776 for (p = 0; p < 2; ++p) { 5777 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); 5778 } 5779 for (p = 2; p < 6; ++p) { 5780 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); 5781 } 5782 #endif 5783 } 5784 } 5785 /* Interior split faces have 4 edges and the same cells as the parent */ 5786 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5787 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5788 for (f = fStart; f < fMax; ++f) { 5789 for (r = 0; r < 4; ++r) { 5790 /* TODO: This can come from GetFaces_Internal() */ 5791 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}; 5792 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 5793 const PetscInt *cone, *ornt, *support; 5794 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 5795 5796 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5797 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5798 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 5799 orntNew[(r+3)%4] = ornt[(r+3)%4]; 5800 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 5801 orntNew[(r+0)%4] = ornt[r]; 5802 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 5803 orntNew[(r+1)%4] = 0; 5804 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 5805 orntNew[(r+2)%4] = -2; 5806 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5807 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);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 < 4; ++p) { 5811 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); 5812 } 5813 #endif 5814 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5815 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5816 for (s = 0; s < supportSize; ++s) { 5817 PetscInt subf; 5818 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5819 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5820 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5821 for (c = 0; c < coneSize; ++c) { 5822 if (cone[c] == f) break; 5823 } 5824 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 5825 if (support[s] < cMax) { 5826 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 5827 } else { 5828 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 5829 } 5830 } 5831 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5832 #if 1 5833 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5834 for (p = 0; p < supportSize; ++p) { 5835 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); 5836 } 5837 #endif 5838 } 5839 } 5840 /* Interior cell faces have 4 edges and 2 cells */ 5841 for (c = cStart; c < cMax; ++c) { 5842 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}; 5843 const PetscInt *cone, *ornt; 5844 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 5845 5846 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5847 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5848 /* A-D face */ 5849 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 5850 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 5851 orntNew[0] = 0; 5852 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5853 orntNew[1] = 0; 5854 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5855 orntNew[2] = -2; 5856 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 5857 orntNew[3] = -2; 5858 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5859 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5860 #if 1 5861 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5862 for (p = 0; p < 4; ++p) { 5863 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); 5864 } 5865 #endif 5866 /* C-D face */ 5867 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 5868 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 5869 orntNew[0] = 0; 5870 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5871 orntNew[1] = 0; 5872 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5873 orntNew[2] = -2; 5874 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 5875 orntNew[3] = -2; 5876 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5877 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5878 #if 1 5879 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5880 for (p = 0; p < 4; ++p) { 5881 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); 5882 } 5883 #endif 5884 /* B-C face */ 5885 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 5886 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 5887 orntNew[0] = -2; 5888 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 5889 orntNew[1] = 0; 5890 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5891 orntNew[2] = 0; 5892 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5893 orntNew[3] = -2; 5894 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5895 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5896 #if 1 5897 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5898 for (p = 0; p < 4; ++p) { 5899 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); 5900 } 5901 #endif 5902 /* A-B face */ 5903 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 5904 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 5905 orntNew[0] = -2; 5906 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 5907 orntNew[1] = 0; 5908 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5909 orntNew[2] = 0; 5910 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 5911 orntNew[3] = -2; 5912 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5913 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5914 #if 1 5915 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5916 for (p = 0; p < 4; ++p) { 5917 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); 5918 } 5919 #endif 5920 /* E-F face */ 5921 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 5922 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5923 orntNew[0] = -2; 5924 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 5925 orntNew[1] = -2; 5926 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 5927 orntNew[2] = 0; 5928 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5929 orntNew[3] = 0; 5930 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5931 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5932 #if 1 5933 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5934 for (p = 0; p < 4; ++p) { 5935 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); 5936 } 5937 #endif 5938 /* F-G face */ 5939 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 5940 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 5941 orntNew[0] = -2; 5942 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 5943 orntNew[1] = -2; 5944 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 5945 orntNew[2] = 0; 5946 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5947 orntNew[3] = 0; 5948 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5949 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5950 #if 1 5951 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5952 for (p = 0; p < 4; ++p) { 5953 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); 5954 } 5955 #endif 5956 /* G-H face */ 5957 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 5958 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 5959 orntNew[0] = -2; 5960 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 5961 orntNew[1] = 0; 5962 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5963 orntNew[2] = 0; 5964 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 5965 orntNew[3] = -2; 5966 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5967 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5968 #if 1 5969 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5970 for (p = 0; p < 4; ++p) { 5971 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); 5972 } 5973 #endif 5974 /* E-H face */ 5975 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 5976 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5977 orntNew[0] = -2; 5978 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 5979 orntNew[1] = -2; 5980 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 5981 orntNew[2] = 0; 5982 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 5983 orntNew[3] = 0; 5984 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5985 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5986 #if 1 5987 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 5988 for (p = 0; p < 4; ++p) { 5989 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); 5990 } 5991 #endif 5992 /* A-E face */ 5993 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 5994 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 5995 orntNew[0] = 0; 5996 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 5997 orntNew[1] = 0; 5998 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 5999 orntNew[2] = -2; 6000 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 6001 orntNew[3] = -2; 6002 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6003 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6004 #if 1 6005 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 6006 for (p = 0; p < 4; ++p) { 6007 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); 6008 } 6009 #endif 6010 /* D-F face */ 6011 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 6012 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 6013 orntNew[0] = -2; 6014 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 6015 orntNew[1] = 0; 6016 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 6017 orntNew[2] = 0; 6018 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 6019 orntNew[3] = -2; 6020 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6021 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6022 #if 1 6023 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 6024 for (p = 0; p < 4; ++p) { 6025 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); 6026 } 6027 #endif 6028 /* C-G face */ 6029 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 6030 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 6031 orntNew[0] = -2; 6032 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 6033 orntNew[1] = -2; 6034 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 6035 orntNew[2] = 0; 6036 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 6037 orntNew[3] = 0; 6038 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6039 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6040 #if 1 6041 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 6042 for (p = 0; p < 4; ++p) { 6043 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); 6044 } 6045 #endif 6046 /* B-H face */ 6047 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 6048 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 6049 orntNew[0] = 0; 6050 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 6051 orntNew[1] = -2; 6052 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 6053 orntNew[2] = -2; 6054 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 6055 orntNew[3] = 0; 6056 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6057 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6058 #if 1 6059 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 6060 for (p = 0; p < 4; ++p) { 6061 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); 6062 } 6063 #endif 6064 for (r = 0; r < 12; ++r) { 6065 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 6066 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 6067 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 6068 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6069 #if 1 6070 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 6071 for (p = 0; p < 2; ++p) { 6072 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); 6073 } 6074 #endif 6075 } 6076 } 6077 /* Hybrid split faces have 4 edges and same cells */ 6078 for (f = fMax; f < fEnd; ++f) { 6079 const PetscInt *cone, *ornt, *support; 6080 PetscInt coneNew[4], orntNew[4]; 6081 PetscInt supportNew[2], size, s, c; 6082 6083 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6084 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6085 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6086 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6087 for (r = 0; r < 2; ++r) { 6088 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 6089 6090 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 6091 orntNew[0] = ornt[0]; 6092 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 6093 orntNew[1] = ornt[1]; 6094 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 6095 orntNew[2+r] = 0; 6096 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 6097 orntNew[3-r] = 0; 6098 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6099 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6100 #if 1 6101 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 6102 for (p = 0; p < 2; ++p) { 6103 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); 6104 } 6105 for (p = 2; p < 4; ++p) { 6106 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); 6107 } 6108 #endif 6109 for (s = 0; s < size; ++s) { 6110 const PetscInt *coneCell, *orntCell, *fornt; 6111 PetscInt o, of; 6112 6113 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6114 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6115 o = orntCell[0] < 0 ? -1 : 1; 6116 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 6117 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 6118 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 6119 of = fornt[c-2] < 0 ? -1 : 1; 6120 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 6121 } 6122 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6123 #if 1 6124 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 6125 for (p = 0; p < size; ++p) { 6126 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); 6127 } 6128 #endif 6129 } 6130 } 6131 /* Hybrid cell faces have 4 edges and 2 cells */ 6132 for (c = cMax; c < cEnd; ++c) { 6133 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 6134 const PetscInt *cone, *ornt; 6135 PetscInt coneNew[4], orntNew[4]; 6136 PetscInt supportNew[2]; 6137 6138 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6139 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6140 for (r = 0; r < 4; ++r) { 6141 #if 0 6142 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 6143 orntNew[0] = 0; 6144 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 6145 orntNew[1] = 0; 6146 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 6147 orntNew[2] = 0; 6148 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6149 orntNew[3] = 0; 6150 #else 6151 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 6152 orntNew[0] = 0; 6153 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 6154 orntNew[1] = 0; 6155 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 6156 orntNew[2] = 0; 6157 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6158 orntNew[3] = 0; 6159 #endif 6160 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 6161 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 6162 #if 1 6163 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); 6164 for (p = 0; p < 2; ++p) { 6165 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); 6166 } 6167 for (p = 2; p < 4; ++p) { 6168 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); 6169 } 6170 #endif 6171 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 6172 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 6173 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 6174 #if 1 6175 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); 6176 for (p = 0; p < 2; ++p) { 6177 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); 6178 } 6179 #endif 6180 } 6181 } 6182 /* Interior split edges have 2 vertices and the same faces as the parent */ 6183 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6184 for (e = eStart; e < eMax; ++e) { 6185 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6186 6187 for (r = 0; r < 2; ++r) { 6188 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6189 const PetscInt *cone, *ornt, *support; 6190 PetscInt coneNew[2], coneSize, c, supportSize, s; 6191 6192 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6193 coneNew[0] = vStartNew + (cone[0] - vStart); 6194 coneNew[1] = vStartNew + (cone[1] - vStart); 6195 coneNew[(r+1)%2] = newv; 6196 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6197 #if 1 6198 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6199 for (p = 0; p < 2; ++p) { 6200 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); 6201 } 6202 #endif 6203 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6204 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6205 for (s = 0; s < supportSize; ++s) { 6206 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6207 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6208 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6209 for (c = 0; c < coneSize; ++c) { 6210 if (cone[c] == e) break; 6211 } 6212 if (support[s] < fMax) { 6213 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 6214 } else { 6215 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6216 } 6217 } 6218 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6219 #if 1 6220 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6221 for (p = 0; p < supportSize; ++p) { 6222 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); 6223 } 6224 #endif 6225 } 6226 } 6227 /* Interior face edges have 2 vertices and 2+cells faces */ 6228 for (f = fStart; f < fMax; ++f) { 6229 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}; 6230 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6231 const PetscInt *cone, *coneCell, *orntCell, *support; 6232 PetscInt coneNew[2], coneSize, c, supportSize, s; 6233 6234 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6235 for (r = 0; r < 4; ++r) { 6236 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 6237 6238 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6239 coneNew[1] = newv; 6240 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6241 #if 1 6242 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6243 for (p = 0; p < 2; ++p) { 6244 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); 6245 } 6246 #endif 6247 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6248 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6249 supportRef[0] = fStartNew + (f - fStart)*4 + r; 6250 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 6251 for (s = 0; s < supportSize; ++s) { 6252 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6253 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6254 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6255 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 6256 if (support[s] < cMax) { 6257 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 6258 } else { 6259 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 6260 } 6261 } 6262 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6263 #if 1 6264 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6265 for (p = 0; p < 2+supportSize; ++p) { 6266 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); 6267 } 6268 #endif 6269 } 6270 } 6271 /* Interior cell edges have 2 vertices and 4 faces */ 6272 for (c = cStart; c < cMax; ++c) { 6273 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}; 6274 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 6275 const PetscInt *cone; 6276 PetscInt coneNew[2], supportNew[4]; 6277 6278 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6279 for (r = 0; r < 6; ++r) { 6280 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 6281 6282 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6283 coneNew[1] = newv; 6284 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6285 #if 1 6286 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6287 for (p = 0; p < 2; ++p) { 6288 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); 6289 } 6290 #endif 6291 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 6292 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6293 #if 1 6294 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 6295 for (p = 0; p < 4; ++p) { 6296 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); 6297 } 6298 #endif 6299 } 6300 } 6301 /* Hybrid edges have two vertices and the same faces */ 6302 for (e = eMax; e < eEnd; ++e) { 6303 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 6304 const PetscInt *cone, *support, *fcone; 6305 PetscInt coneNew[2], size, fsize, s; 6306 6307 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6308 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6309 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6310 coneNew[0] = vStartNew + (cone[0] - vStart); 6311 coneNew[1] = vStartNew + (cone[1] - vStart); 6312 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6313 #if 1 6314 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6315 for (p = 0; p < 2; ++p) { 6316 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); 6317 } 6318 #endif 6319 for (s = 0; s < size; ++s) { 6320 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6321 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6322 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6323 if ((c < 2) || (c > 3)) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 6324 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 6325 } 6326 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6327 #if 1 6328 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6329 for (p = 0; p < size; ++p) { 6330 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); 6331 } 6332 #endif 6333 } 6334 /* Hybrid face edges have 2 vertices and 2+cells faces */ 6335 for (f = fMax; f < fEnd; ++f) { 6336 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 6337 const PetscInt *cone, *support, *ccone, *cornt; 6338 PetscInt coneNew[2], size, csize, s; 6339 6340 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6341 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6342 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6343 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6344 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6345 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6346 #if 1 6347 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6348 for (p = 0; p < 2; ++p) { 6349 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); 6350 } 6351 #endif 6352 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 6353 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 6354 for (s = 0; s < size; ++s) { 6355 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 6356 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 6357 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 6358 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 6359 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]); 6360 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 6361 } 6362 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6363 #if 1 6364 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6365 for (p = 0; p < 2+size; ++p) { 6366 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); 6367 } 6368 #endif 6369 } 6370 /* Hybrid cell edges have 2 vertices and 4 faces */ 6371 for (c = cMax; c < cEnd; ++c) { 6372 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 6373 const PetscInt *cone, *support; 6374 PetscInt coneNew[2], size; 6375 6376 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6377 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 6378 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 6379 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6380 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6381 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6382 #if 1 6383 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6384 for (p = 0; p < 2; ++p) { 6385 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); 6386 } 6387 #endif 6388 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 6389 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 6390 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 6391 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 6392 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6393 #if 1 6394 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 6395 for (p = 0; p < 4; ++p) { 6396 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); 6397 } 6398 #endif 6399 } 6400 /* Interior vertices have identical supports */ 6401 for (v = vStart; v < vEnd; ++v) { 6402 const PetscInt newp = vStartNew + (v - vStart); 6403 const PetscInt *support, *cone; 6404 PetscInt size, s; 6405 6406 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6407 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6408 for (s = 0; s < size; ++s) { 6409 PetscInt r = 0; 6410 6411 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6412 if (cone[1] == v) r = 1; 6413 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 6414 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 6415 } 6416 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6417 #if 1 6418 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6419 for (p = 0; p < size; ++p) { 6420 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); 6421 } 6422 #endif 6423 } 6424 /* Interior edge vertices have 2 + faces supports */ 6425 for (e = eStart; e < eMax; ++e) { 6426 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6427 const PetscInt *cone, *support; 6428 PetscInt size, s; 6429 6430 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6431 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6432 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6433 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6434 for (s = 0; s < size; ++s) { 6435 PetscInt r; 6436 6437 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6438 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 6439 if (support[s] < fMax) { 6440 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 6441 } else { 6442 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 6443 } 6444 } 6445 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6446 #if 1 6447 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6448 for (p = 0; p < 2+size; ++p) { 6449 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); 6450 } 6451 #endif 6452 } 6453 /* Interior face vertices have 4 + cells supports */ 6454 for (f = fStart; f < fMax; ++f) { 6455 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6456 const PetscInt *cone, *support; 6457 PetscInt size, s; 6458 6459 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6460 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6461 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 6462 for (s = 0; s < size; ++s) { 6463 PetscInt r; 6464 6465 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6466 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 6467 if (support[s] < cMax) { 6468 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 6469 } else { 6470 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 6471 } 6472 } 6473 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6474 #if 1 6475 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6476 for (p = 0; p < 4+size; ++p) { 6477 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); 6478 } 6479 #endif 6480 } 6481 /* Cell vertices have 6 supports */ 6482 for (c = cStart; c < cMax; ++c) { 6483 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 6484 PetscInt supportNew[6]; 6485 6486 for (r = 0; r < 6; ++r) { 6487 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 6488 } 6489 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6490 } 6491 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6492 break; 6493 default: 6494 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6495 } 6496 PetscFunctionReturn(0); 6497 } 6498 6499 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 6500 { 6501 PetscSection coordSection, coordSectionNew; 6502 Vec coordinates, coordinatesNew; 6503 PetscScalar *coords, *coordsNew; 6504 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 6505 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 6506 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 6507 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 6508 VecType vtype; 6509 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 6510 const PetscReal *maxCell, *L; 6511 const DMBoundaryType *bd; 6512 PetscErrorCode ierr; 6513 6514 PetscFunctionBegin; 6515 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 6516 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 6517 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 6518 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 6519 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 6520 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 6521 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 6522 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 6523 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 6524 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 6525 /* Determine if we need to localize coordinates when generating them */ 6526 if (isperiodic && !maxCell) { 6527 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 6528 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 6529 } 6530 if (isperiodic) { 6531 ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr); 6532 ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr); 6533 ierr = PetscOptionsEnd();CHKERRQ(ierr); 6534 if (localize) { 6535 ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 6536 } 6537 } 6538 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 6539 6540 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 6541 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 6542 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 6543 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 6544 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 6545 6546 if (localize) { 6547 PetscInt p, r, newp, *pi; 6548 6549 /* New coordinates will be already localized on the cell */ 6550 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 6551 6552 /* We need the parentId to properly localize coordinates */ 6553 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 6554 switch (refiner) { 6555 case REFINER_NOOP: 6556 break; 6557 case REFINER_SIMPLEX_1D: 6558 for (p = cStart; p < cEnd; ++p) { 6559 for (r = 0; r < 2; ++r) { 6560 newp = (p - cStart)*2 + r; 6561 pi[newp] = p; 6562 } 6563 } 6564 break; 6565 case REFINER_SIMPLEX_2D: 6566 for (p = cStart; p < cEnd; ++p) { 6567 for (r = 0; r < 4; ++r) { 6568 newp = (p - cStart)*4 + r; 6569 pi[newp] = p; 6570 } 6571 } 6572 break; 6573 case REFINER_HEX_2D: 6574 for (p = cStart; p < cEnd; ++p) { 6575 for (r = 0; r < 4; ++r) { 6576 newp = (p - cStart)*4 + r; 6577 pi[newp] = p; 6578 } 6579 } 6580 break; 6581 case REFINER_SIMPLEX_TO_HEX_2D: 6582 for (p = cStart; p < cEnd; ++p) { 6583 for (r = 0; r < 3; ++r) { 6584 newp = (p - cStart)*3 + r; 6585 pi[newp] = p; 6586 } 6587 } 6588 break; 6589 case REFINER_HYBRID_SIMPLEX_2D: 6590 for (p = cStart; p < cMax; ++p) { 6591 for (r = 0; r < 4; ++r) { 6592 newp = (p - cStart)*4 + r; 6593 pi[newp] = p; 6594 } 6595 } 6596 for (p = cMax; p < cEnd; ++p) { 6597 for (r = 0; r < 2; ++r) { 6598 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 6599 pi[newp] = p; 6600 } 6601 } 6602 break; 6603 case REFINER_HYBRID_HEX_2D: 6604 for (p = cStart; p < cMax; ++p) { 6605 for (r = 0; r < 4; ++r) { 6606 newp = (p - cStart)*4 + r; 6607 pi[newp] = p; 6608 } 6609 } 6610 for (p = cMax; p < cEnd; ++p) { 6611 for (r = 0; r < 2; ++r) { 6612 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 6613 pi[newp] = p; 6614 } 6615 } 6616 break; 6617 case REFINER_SIMPLEX_3D: 6618 for (p = cStart; p < cEnd; ++p) { 6619 for (r = 0; r < 8; ++r) { 6620 newp = (p - cStart)*8 + r; 6621 pi[newp] = p; 6622 } 6623 } 6624 break; 6625 case REFINER_HYBRID_SIMPLEX_3D: 6626 for (p = cStart; p < cMax; ++p) { 6627 for (r = 0; r < 8; ++r) { 6628 newp = (p - cStart)*8 + r; 6629 pi[newp] = p; 6630 } 6631 } 6632 for (p = cMax; p < cEnd; ++p) { 6633 for (r = 0; r < 4; ++r) { 6634 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 6635 pi[newp] = p; 6636 } 6637 } 6638 break; 6639 case REFINER_SIMPLEX_TO_HEX_3D: 6640 for (p = cStart; p < cEnd; ++p) { 6641 for (r = 0; r < 4; ++r) { 6642 newp = (p - cStart)*4 + r; 6643 pi[newp] = p; 6644 } 6645 } 6646 break; 6647 case REFINER_HEX_3D: 6648 for (p = cStart; p < cEnd; ++p) { 6649 for (r = 0; r < 8; ++r) { 6650 newp = (p - cStart)*8 + r; 6651 pi[newp] = p; 6652 } 6653 } 6654 break; 6655 case REFINER_HYBRID_HEX_3D: 6656 for (p = cStart; p < cMax; ++p) { 6657 for (r = 0; r < 8; ++r) { 6658 newp = (p - cStart)*8 + r; 6659 pi[newp] = p; 6660 } 6661 } 6662 for (p = cMax; p < cEnd; ++p) { 6663 for (r = 0; r < 4; ++r) { 6664 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 6665 pi[newp] = p; 6666 } 6667 } 6668 break; 6669 default: 6670 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 6671 } 6672 parentId = pi; 6673 } else { 6674 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 6675 } 6676 if (cMax < 0) cMax = cEnd; 6677 if (fMax < 0) fMax = fEnd; 6678 if (eMax < 0) eMax = eEnd; 6679 6680 /* All vertices have the spaceDim coordinates */ 6681 if (localize) { 6682 PetscInt c; 6683 6684 for (c = cStartNew; c < cEndNew; ++c) { 6685 PetscInt *cone = NULL; 6686 PetscInt closureSize, coneSize = 0, p, pdof; 6687 6688 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 6689 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 6690 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6691 for (p = 0; p < closureSize*2; p += 2) { 6692 const PetscInt point = cone[p]; 6693 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 6694 } 6695 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6696 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 6697 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 6698 } 6699 } 6700 } 6701 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 6702 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 6703 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 6704 } 6705 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 6706 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 6707 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 6708 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 6709 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 6710 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 6711 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 6712 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 6713 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 6714 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 6715 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 6716 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 6717 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 6718 6719 switch (refiner) { 6720 case REFINER_NOOP: break; 6721 case REFINER_SIMPLEX_TO_HEX_3D: 6722 case REFINER_HEX_3D: 6723 case REFINER_HYBRID_HEX_3D: 6724 /* Face vertices have the average of corner coordinates */ 6725 for (f = fStart; f < fMax; ++f) { 6726 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6727 PetscInt *cone = NULL; 6728 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 6729 6730 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6731 for (p = 0; p < closureSize*2; p += 2) { 6732 const PetscInt point = cone[p]; 6733 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6734 } 6735 if (localize) { 6736 const PetscInt *support = NULL; 6737 PetscInt *rStar = NULL; 6738 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 6739 PetscBool cellfound = PETSC_FALSE; 6740 6741 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6742 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 6743 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 6744 /* Compute average of coordinates for each cell sharing the face */ 6745 for (s = 0; s < supportSize; ++s) { 6746 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 6747 PetscInt *cellCone = NULL; 6748 PetscInt cellClosureSize, cellConeSize = 0, cdof; 6749 const PetscInt cell = support[s]; 6750 PetscBool copyoff = PETSC_FALSE; 6751 6752 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6753 for (p = 0; p < cellClosureSize*2; p += 2) { 6754 const PetscInt point = cellCone[p]; 6755 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 6756 } 6757 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 6758 if (!cdof) { /* the parent cell does not have localized coordinates */ 6759 cellfound = PETSC_TRUE; 6760 for (v = 0; v < coneSize; ++v) { 6761 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6762 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 6763 } 6764 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 6765 } else { 6766 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 6767 for (p = 0; p < coneSize; ++p) { 6768 const PetscInt tv = cone[p]; 6769 PetscInt cv, voff; 6770 PetscBool locv = PETSC_TRUE; 6771 6772 for (cv = 0; cv < cellConeSize; ++cv) { 6773 if (cellCone[cv] == tv) { 6774 ccoff[p] = spaceDim*cv + coff; 6775 break; 6776 } 6777 } 6778 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D\n",tv); 6779 6780 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 6781 for (d = 0; d < spaceDim; ++d) { 6782 coordsNewAux[d] += coords[ccoff[p]+d]; 6783 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 6784 } 6785 if (locv && !cellfound) { 6786 cellfound = PETSC_TRUE; 6787 copyoff = PETSC_TRUE; 6788 } 6789 } 6790 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 6791 6792 /* Found a valid face for the "vertex" part of the Section (physical space) 6793 i.e., a face that has at least one corner in the physical space */ 6794 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 6795 } 6796 6797 /* Localize new coordinates on each refined cell */ 6798 for (v = 0; v < rStarSize*2; v += 2) { 6799 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 6800 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 6801 const PetscInt rcell = rStar[v]; 6802 6803 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 6804 if (!rcdof) continue; 6805 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 6806 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6807 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 6808 if (rcone[p] == newv) { 6809 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 6810 break; 6811 } 6812 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 6813 } 6814 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6815 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6816 } 6817 } 6818 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6819 } 6820 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6821 if (!cellfound) { 6822 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 6823 needcoords = PETSC_TRUE; 6824 coneSize = 0; 6825 } 6826 } else { 6827 for (v = 0; v < coneSize; ++v) { 6828 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6829 } 6830 } 6831 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6832 if (coneSize) { 6833 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6834 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6835 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6836 } else { 6837 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 6838 } 6839 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6840 } 6841 case REFINER_SIMPLEX_TO_HEX_2D: 6842 case REFINER_HEX_2D: 6843 case REFINER_HYBRID_HEX_2D: 6844 case REFINER_SIMPLEX_1D: 6845 /* Cell vertices have the average of corner coordinates */ 6846 for (c = cStart; c < cMax; ++c) { 6847 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 6848 PetscInt *cone = NULL; 6849 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 6850 6851 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6852 for (p = 0; p < closureSize*2; p += 2) { 6853 const PetscInt point = cone[p]; 6854 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 6855 } 6856 if (localize) { 6857 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 6858 } 6859 if (cdof) { 6860 PetscInt coff; 6861 6862 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 6863 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 6864 } else { 6865 for (v = 0; v < coneSize; ++v) { 6866 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 6867 } 6868 } 6869 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 6870 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 6871 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 6872 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 6873 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6874 6875 /* Localize new coordinates on each refined cell */ 6876 if (cdof) { 6877 PetscInt *rStar = NULL, rStarSize; 6878 6879 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6880 for (v = 0; v < rStarSize*2; v += 2) { 6881 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 6882 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 6883 6884 rc = rStar[v]; 6885 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 6886 if (!rcdof) continue; 6887 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 6888 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6889 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 6890 if (cone[p] == newv) { 6891 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 6892 break; 6893 } 6894 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 6895 } 6896 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6897 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 6898 } 6899 } 6900 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6901 } 6902 } 6903 case REFINER_SIMPLEX_2D: 6904 case REFINER_HYBRID_SIMPLEX_2D: 6905 case REFINER_SIMPLEX_3D: 6906 case REFINER_HYBRID_SIMPLEX_3D: 6907 /* Edge vertices have the average of endpoint coordinates */ 6908 for (e = eStart; e < eMax; ++e) { 6909 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6910 const PetscInt *cone; 6911 PetscInt coneSize, offA, offB, offnew, d; 6912 6913 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 6914 if (coneSize != 2) SETERRQ2(PetscObjectComm((PetscObject)dm), PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 6915 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6916 if (localize) { 6917 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 6918 PetscInt *eStar = NULL, eStarSize; 6919 PetscInt *rStar = NULL, rStarSize; 6920 PetscBool cellfound = PETSC_FALSE; 6921 6922 offA = offB = -1; 6923 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 6924 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 6925 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 6926 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6927 for (v = 0; v < eStarSize*2; v += 2) { 6928 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 6929 PetscScalar coordsNewAux[3]; 6930 PetscInt *cellCone = NULL; 6931 PetscInt cellClosureSize, s, cv, cdof; 6932 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 6933 const PetscInt cell = eStar[v]; 6934 6935 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 6936 if (!cdof) { 6937 /* Found a valid edge for the "vertex" part of the Section */ 6938 offA = voffA; 6939 offB = voffB; 6940 cellfound = PETSC_TRUE; 6941 } else { 6942 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 6943 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6944 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 6945 const PetscInt point = cellCone[s]; 6946 if ((point >= vStart) && (point < vEnd)) { 6947 if (point == cone[0]) toffA = spaceDim*cv + coff; 6948 else if (point == cone[1]) toffB = spaceDim*cv + coff; 6949 cv++; 6950 } 6951 } 6952 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 6953 for (d = 0; d < spaceDim; ++d) { 6954 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 6955 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 6956 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 6957 } 6958 /* Found a valid edge for the "vertex" part of the Section */ 6959 if (!cellfound && (locvA || locvB)) { 6960 cellfound = PETSC_TRUE; 6961 offA = toffA; 6962 offB = toffB; 6963 } 6964 } 6965 6966 /* Localize new coordinates on each refined cell */ 6967 for (s = 0; s < rStarSize*2; s += 2) { 6968 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 6969 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 6970 const PetscInt rcell = rStar[s]; 6971 6972 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 6973 if (!rcdof) continue; 6974 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 6975 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6976 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 6977 if (rcone[p] == newv) { 6978 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 6979 break; 6980 } 6981 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 6982 } 6983 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 6984 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 6985 } 6986 } 6987 } 6988 } 6989 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 6990 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 6991 if (!cellfound) { 6992 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 6993 needcoords = PETSC_TRUE; 6994 } 6995 } else { 6996 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 6997 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 6998 } 6999 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 7000 if (offA != -1 && offB != -1) { 7001 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 7002 for (d = 0; d < spaceDim; ++d) { 7003 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 7004 } 7005 } else { 7006 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 7007 } 7008 } 7009 /* Old vertices have the same coordinates */ 7010 for (v = vStart; v < vEnd; ++v) { 7011 const PetscInt newv = vStartNew + (v - vStart); 7012 PetscInt off, offnew, d; 7013 7014 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 7015 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 7016 for (d = 0; d < spaceDim; ++d) { 7017 coordsNew[offnew+d] = coords[off+d]; 7018 } 7019 7020 /* Localize new coordinates on each refined cell */ 7021 if (localize) { 7022 PetscInt p; 7023 PetscInt *rStar = NULL, rStarSize; 7024 7025 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 7026 for (p = 0; p < rStarSize*2; p += 2) { 7027 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 7028 PetscScalar ocoords[3]; 7029 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 7030 7031 c = rStar[p]; 7032 oc = parentId[c-cStartNew]; 7033 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 7034 if (!cdof) continue; 7035 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 7036 if (!cdof) continue; 7037 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 7038 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7039 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 7040 if (cone[s] == v) { 7041 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 7042 break; 7043 } 7044 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 7045 } 7046 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D\n",v); 7047 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7048 7049 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 7050 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7051 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 7052 if (cone[s] == newv) { 7053 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 7054 break; 7055 } 7056 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 7057 } 7058 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 7059 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 7060 } 7061 } 7062 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 7063 } 7064 } 7065 break; 7066 default: 7067 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7068 } 7069 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 7070 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 7071 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 7072 7073 /* Final reduction (if needed) if we are localizing */ 7074 if (localize) { 7075 PetscBool gred; 7076 7077 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 7078 if (gred) { 7079 DM cdm; 7080 Vec aux; 7081 PetscSF sf; 7082 const PetscScalar *lArray; 7083 PetscScalar *gArray; 7084 7085 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 7086 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 7087 ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr); 7088 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 7089 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 7090 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 7091 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 7092 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 7093 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 7094 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 7095 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 7096 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 7097 ierr = VecDestroy(&aux);CHKERRQ(ierr); 7098 } 7099 } 7100 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 7101 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 7102 ierr = PetscFree(parentId);CHKERRQ(ierr); 7103 PetscFunctionReturn(0); 7104 } 7105 7106 /*@ 7107 DMPlexCreateProcessSF - Create an SF which just has process connectivity 7108 7109 Collective on DM 7110 7111 Input Parameters: 7112 + dm - The DM 7113 - sfPoint - The PetscSF which encodes point connectivity 7114 7115 Output Parameters: 7116 + processRanks - A list of process neighbors, or NULL 7117 - sfProcess - An SF encoding the process connectivity, or NULL 7118 7119 Level: developer 7120 7121 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 7122 @*/ 7123 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 7124 { 7125 PetscInt numRoots, numLeaves, l; 7126 const PetscInt *localPoints; 7127 const PetscSFNode *remotePoints; 7128 PetscInt *localPointsNew; 7129 PetscSFNode *remotePointsNew; 7130 PetscInt *ranks, *ranksNew; 7131 PetscMPIInt size; 7132 PetscErrorCode ierr; 7133 7134 PetscFunctionBegin; 7135 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7136 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 7137 if (processRanks) {PetscValidPointer(processRanks, 3);} 7138 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 7139 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 7140 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 7141 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 7142 for (l = 0; l < numLeaves; ++l) { 7143 ranks[l] = remotePoints[l].rank; 7144 } 7145 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 7146 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 7147 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 7148 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 7149 for (l = 0; l < numLeaves; ++l) { 7150 ranksNew[l] = ranks[l]; 7151 localPointsNew[l] = l; 7152 remotePointsNew[l].index = 0; 7153 remotePointsNew[l].rank = ranksNew[l]; 7154 } 7155 ierr = PetscFree(ranks);CHKERRQ(ierr); 7156 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 7157 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 7158 if (sfProcess) { 7159 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 7160 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 7161 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 7162 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 7163 } 7164 PetscFunctionReturn(0); 7165 } 7166 7167 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 7168 { 7169 PetscSF sf, sfNew, sfProcess; 7170 IS processRanks; 7171 MPI_Datatype depthType; 7172 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 7173 const PetscInt *localPoints, *neighbors; 7174 const PetscSFNode *remotePoints; 7175 PetscInt *localPointsNew; 7176 PetscSFNode *remotePointsNew; 7177 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 7178 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 7179 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7180 PetscErrorCode ierr; 7181 7182 PetscFunctionBegin; 7183 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 7184 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 7185 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 7186 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth); 7187 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7188 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 7189 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7190 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7191 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7192 cMax = cMax < 0 ? cEnd : cMax; 7193 fMax = fMax < 0 ? fEnd : fMax; 7194 eMax = eMax < 0 ? eEnd : eMax; 7195 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7196 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 7197 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 7198 /* Calculate size of new SF */ 7199 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 7200 if (numRoots < 0) PetscFunctionReturn(0); 7201 for (l = 0; l < numLeaves; ++l) { 7202 const PetscInt p = localPoints[l]; 7203 7204 switch (refiner) { 7205 case REFINER_SIMPLEX_1D: 7206 if ((p >= vStart) && (p < vEnd)) { 7207 /* Interior vertices stay the same */ 7208 ++numLeavesNew; 7209 } else if ((p >= cStart && p < cMax)) { 7210 /* Interior cells add new cells and interior vertices */ 7211 numLeavesNew += 2 + 1; 7212 } 7213 break; 7214 case REFINER_SIMPLEX_2D: 7215 case REFINER_HYBRID_SIMPLEX_2D: 7216 if ((p >= vStart) && (p < vEnd)) { 7217 /* Interior vertices stay the same */ 7218 ++numLeavesNew; 7219 } else if ((p >= fStart) && (p < fMax)) { 7220 /* Interior faces add new faces and vertex */ 7221 numLeavesNew += 2 + 1; 7222 } else if ((p >= fMax) && (p < fEnd)) { 7223 /* Hybrid faces stay the same */ 7224 ++numLeavesNew; 7225 } else if ((p >= cStart) && (p < cMax)) { 7226 /* Interior cells add new cells and interior faces */ 7227 numLeavesNew += 4 + 3; 7228 } else if ((p >= cMax) && (p < cEnd)) { 7229 /* Hybrid cells add new cells and hybrid face */ 7230 numLeavesNew += 2 + 1; 7231 } 7232 break; 7233 case REFINER_SIMPLEX_TO_HEX_2D: 7234 if ((p >= vStart) && (p < vEnd)) { 7235 /* Interior vertices stay the same */ 7236 ++numLeavesNew; 7237 } else if ((p >= fStart) && (p < fEnd)) { 7238 /* Interior faces add new faces and vertex */ 7239 numLeavesNew += 2 + 1; 7240 } else if ((p >= cStart) && (p < cEnd)) { 7241 /* Interior cells add new cells, interior faces, and vertex */ 7242 numLeavesNew += 3 + 3 + 1; 7243 } 7244 break; 7245 case REFINER_HEX_2D: 7246 case REFINER_HYBRID_HEX_2D: 7247 if ((p >= vStart) && (p < vEnd)) { 7248 /* Interior vertices stay the same */ 7249 ++numLeavesNew; 7250 } else if ((p >= fStart) && (p < fMax)) { 7251 /* Interior faces add new faces and vertex */ 7252 numLeavesNew += 2 + 1; 7253 } else if ((p >= fMax) && (p < fEnd)) { 7254 /* Hybrid faces stay the same */ 7255 ++numLeavesNew; 7256 } else if ((p >= cStart) && (p < cMax)) { 7257 /* Interior cells add new cells, interior faces, and vertex */ 7258 numLeavesNew += 4 + 4 + 1; 7259 } else if ((p >= cMax) && (p < cEnd)) { 7260 /* Hybrid cells add new cells and hybrid face */ 7261 numLeavesNew += 2 + 1; 7262 } 7263 break; 7264 case REFINER_SIMPLEX_3D: 7265 case REFINER_HYBRID_SIMPLEX_3D: 7266 if ((p >= vStart) && (p < vEnd)) { 7267 /* Interior vertices stay the same */ 7268 ++numLeavesNew; 7269 } else if ((p >= eStart) && (p < eMax)) { 7270 /* Interior edges add new edges and vertex */ 7271 numLeavesNew += 2 + 1; 7272 } else if ((p >= eMax) && (p < eEnd)) { 7273 /* Hybrid edges stay the same */ 7274 ++numLeavesNew; 7275 } else if ((p >= fStart) && (p < fMax)) { 7276 /* Interior faces add new faces and edges */ 7277 numLeavesNew += 4 + 3; 7278 } else if ((p >= fMax) && (p < fEnd)) { 7279 /* Hybrid faces add new faces and edges */ 7280 numLeavesNew += 2 + 1; 7281 } else if ((p >= cStart) && (p < cMax)) { 7282 /* Interior cells add new cells, faces, and edges */ 7283 numLeavesNew += 8 + 8 + 1; 7284 } else if ((p >= cMax) && (p < cEnd)) { 7285 /* Hybrid cells add new cells and faces */ 7286 numLeavesNew += 4 + 3; 7287 } 7288 break; 7289 case REFINER_SIMPLEX_TO_HEX_3D: 7290 if ((p >= vStart) && (p < vEnd)) { 7291 /* Interior vertices stay the same */ 7292 ++numLeavesNew; 7293 } else if ((p >= eStart) && (p < eEnd)) { 7294 /* Interior edges add new edges and vertex */ 7295 numLeavesNew += 2 + 1; 7296 } else if ((p >= fStart) && (p < fEnd)) { 7297 /* Interior faces add new faces, edges and a vertex */ 7298 numLeavesNew += 3 + 3 + 1; 7299 } else if ((p >= cStart) && (p < cEnd)) { 7300 /* Interior cells add new cells, faces, edges and a vertex */ 7301 numLeavesNew += 4 + 6 + 4 + 1; 7302 } 7303 break; 7304 case REFINER_HEX_3D: 7305 case REFINER_HYBRID_HEX_3D: 7306 if ((p >= vStart) && (p < vEnd)) { 7307 /* Old vertices stay the same */ 7308 ++numLeavesNew; 7309 } else if ((p >= eStart) && (p < eMax)) { 7310 /* Interior edges add new edges, and vertex */ 7311 numLeavesNew += 2 + 1; 7312 } else if ((p >= eMax) && (p < eEnd)) { 7313 /* Hybrid edges stay the same */ 7314 ++numLeavesNew; 7315 } else if ((p >= fStart) && (p < fMax)) { 7316 /* Interior faces add new faces, edges, and vertex */ 7317 numLeavesNew += 4 + 4 + 1; 7318 } else if ((p >= fMax) && (p < fEnd)) { 7319 /* Hybrid faces add new faces and edges */ 7320 numLeavesNew += 2 + 1; 7321 } else if ((p >= cStart) && (p < cMax)) { 7322 /* Interior cells add new cells, faces, edges, and vertex */ 7323 numLeavesNew += 8 + 12 + 6 + 1; 7324 } else if ((p >= cStart) && (p < cEnd)) { 7325 /* Hybrid cells add new cells, faces, and edges */ 7326 numLeavesNew += 4 + 4 + 1; 7327 } 7328 break; 7329 default: 7330 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7331 } 7332 } 7333 /* Communicate depthSizes for each remote rank */ 7334 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 7335 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 7336 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 7337 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 7338 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 7339 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 7340 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 7341 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 7342 for (n = 0; n < numNeighbors; ++n) { 7343 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 7344 } 7345 depthSizeOld[depth] = cMax; 7346 depthSizeOld[0] = vMax; 7347 depthSizeOld[depth-1] = fMax; 7348 depthSizeOld[1] = eMax; 7349 7350 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 7351 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 7352 7353 depthSizeOld[depth] = cEnd - cStart; 7354 depthSizeOld[0] = vEnd - vStart; 7355 depthSizeOld[depth-1] = fEnd - fStart; 7356 depthSizeOld[1] = eEnd - eStart; 7357 7358 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 7359 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 7360 for (n = 0; n < numNeighbors; ++n) { 7361 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 7362 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 7363 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]; 7364 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 7365 } 7366 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 7367 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 7368 /* Calculate new point SF */ 7369 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 7370 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 7371 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 7372 for (l = 0, m = 0; l < numLeaves; ++l) { 7373 PetscInt p = localPoints[l]; 7374 PetscInt rp = remotePoints[l].index, n; 7375 PetscMPIInt rrank = remotePoints[l].rank; 7376 7377 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 7378 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 7379 switch (refiner) { 7380 case REFINER_SIMPLEX_1D: 7381 if ((p >= vStart) && (p < vEnd)) { 7382 /* Old vertices stay the same */ 7383 localPointsNew[m] = vStartNew + (p - vStart); 7384 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7385 remotePointsNew[m].rank = rrank; 7386 ++m; 7387 } else if ((p >= cStart) && (p < cMax)) { 7388 /* Old interior cells add new cells and vertex */ 7389 for (r = 0; r < 2; ++r, ++m) { 7390 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 7391 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 7392 remotePointsNew[m].rank = rrank; 7393 } 7394 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 7395 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 7396 remotePointsNew[m].rank = rrank; 7397 ++m; 7398 } 7399 break; 7400 case REFINER_SIMPLEX_2D: 7401 case REFINER_HYBRID_SIMPLEX_2D: 7402 if ((p >= vStart) && (p < vEnd)) { 7403 /* Old vertices stay the same */ 7404 localPointsNew[m] = vStartNew + (p - vStart); 7405 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7406 remotePointsNew[m].rank = rrank; 7407 ++m; 7408 } else if ((p >= fStart) && (p < fMax)) { 7409 /* Old interior faces add new faces and vertex */ 7410 for (r = 0; r < 2; ++r, ++m) { 7411 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7412 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7413 remotePointsNew[m].rank = rrank; 7414 } 7415 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7416 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7417 remotePointsNew[m].rank = rrank; 7418 ++m; 7419 } else if ((p >= fMax) && (p < fEnd)) { 7420 /* Old hybrid faces stay the same */ 7421 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 7422 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 7423 remotePointsNew[m].rank = rrank; 7424 ++m; 7425 } else if ((p >= cStart) && (p < cMax)) { 7426 /* Old interior cells add new cells and interior faces */ 7427 for (r = 0; r < 4; ++r, ++m) { 7428 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7429 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7430 remotePointsNew[m].rank = rrank; 7431 } 7432 for (r = 0; r < 3; ++r, ++m) { 7433 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 7434 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 7435 remotePointsNew[m].rank = rrank; 7436 } 7437 } else if ((p >= cMax) && (p < cEnd)) { 7438 /* Old hybrid cells add new cells and hybrid face */ 7439 for (r = 0; r < 2; ++r, ++m) { 7440 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7441 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7442 remotePointsNew[m].rank = rrank; 7443 } 7444 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 7445 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]); 7446 remotePointsNew[m].rank = rrank; 7447 ++m; 7448 } 7449 break; 7450 case REFINER_SIMPLEX_TO_HEX_2D: 7451 if ((p >= vStart) && (p < vEnd)) { 7452 /* Old vertices stay the same */ 7453 localPointsNew[m] = vStartNew + (p - vStart); 7454 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7455 remotePointsNew[m].rank = rrank; 7456 ++m; 7457 } else if ((p >= fStart) && (p < fEnd)) { 7458 /* Old interior faces add new faces and vertex */ 7459 for (r = 0; r < 2; ++r, ++m) { 7460 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7461 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7462 remotePointsNew[m].rank = rrank; 7463 } 7464 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7465 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7466 remotePointsNew[m].rank = rrank; 7467 ++m; 7468 } else if ((p >= cStart) && (p < cEnd)) { 7469 /* Old interior cells add new cells, interior faces, and a vertex */ 7470 for (r = 0; r < 3; ++r, ++m) { 7471 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 7472 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 7473 remotePointsNew[m].rank = rrank; 7474 } 7475 for (r = 0; r < 3; ++r, ++m) { 7476 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7477 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 7478 remotePointsNew[m].rank = rrank; 7479 } 7480 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7481 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 7482 remotePointsNew[m].rank = rrank; 7483 ++m; 7484 } 7485 break; 7486 case REFINER_HEX_2D: 7487 case REFINER_HYBRID_HEX_2D: 7488 if ((p >= vStart) && (p < vEnd)) { 7489 /* Old vertices stay the same */ 7490 localPointsNew[m] = vStartNew + (p - vStart); 7491 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7492 remotePointsNew[m].rank = rrank; 7493 ++m; 7494 } else if ((p >= fStart) && (p < fMax)) { 7495 /* Old interior faces add new faces and vertex */ 7496 for (r = 0; r < 2; ++r, ++m) { 7497 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 7498 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 7499 remotePointsNew[m].rank = rrank; 7500 } 7501 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 7502 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 7503 remotePointsNew[m].rank = rrank; 7504 ++m; 7505 } else if ((p >= fMax) && (p < fEnd)) { 7506 /* Old hybrid faces stay the same */ 7507 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 7508 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 7509 remotePointsNew[m].rank = rrank; 7510 ++m; 7511 } else if ((p >= cStart) && (p < cMax)) { 7512 /* Old interior cells add new cells, interior faces, and vertex */ 7513 for (r = 0; r < 4; ++r, ++m) { 7514 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7515 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7516 remotePointsNew[m].rank = rrank; 7517 } 7518 for (r = 0; r < 4; ++r, ++m) { 7519 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 7520 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 7521 remotePointsNew[m].rank = rrank; 7522 } 7523 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 7524 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 7525 remotePointsNew[m].rank = rrank; 7526 ++m; 7527 } else if ((p >= cStart) && (p < cMax)) { 7528 /* Old hybrid cells add new cells and hybrid face */ 7529 for (r = 0; r < 2; ++r, ++m) { 7530 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7531 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7532 remotePointsNew[m].rank = rrank; 7533 } 7534 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 7535 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]); 7536 remotePointsNew[m].rank = rrank; 7537 ++m; 7538 } 7539 break; 7540 case REFINER_SIMPLEX_3D: 7541 case REFINER_HYBRID_SIMPLEX_3D: 7542 if ((p >= vStart) && (p < vEnd)) { 7543 /* Interior vertices stay the same */ 7544 localPointsNew[m] = vStartNew + (p - vStart); 7545 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7546 remotePointsNew[m].rank = rrank; 7547 ++m; 7548 } else if ((p >= eStart) && (p < eMax)) { 7549 /* Interior edges add new edges and vertex */ 7550 for (r = 0; r < 2; ++r, ++m) { 7551 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7552 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7553 remotePointsNew[m].rank = rrank; 7554 } 7555 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7556 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7557 remotePointsNew[m].rank = rrank; 7558 ++m; 7559 } else if ((p >= eMax) && (p < eEnd)) { 7560 /* Hybrid edges stay the same */ 7561 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 7562 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]); 7563 remotePointsNew[m].rank = rrank; 7564 ++m; 7565 } else if ((p >= fStart) && (p < fMax)) { 7566 /* Interior faces add new faces and edges */ 7567 for (r = 0; r < 4; ++r, ++m) { 7568 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7569 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7570 remotePointsNew[m].rank = rrank; 7571 } 7572 for (r = 0; r < 3; ++r, ++m) { 7573 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 7574 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 7575 remotePointsNew[m].rank = rrank; 7576 } 7577 } else if ((p >= fMax) && (p < fEnd)) { 7578 /* Hybrid faces add new faces and edges */ 7579 for (r = 0; r < 2; ++r, ++m) { 7580 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 7581 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; 7582 remotePointsNew[m].rank = rrank; 7583 } 7584 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 7585 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]); 7586 remotePointsNew[m].rank = rrank; 7587 ++m; 7588 } else if ((p >= cStart) && (p < cMax)) { 7589 /* Interior cells add new cells, faces, and edges */ 7590 for (r = 0; r < 8; ++r, ++m) { 7591 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7592 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7593 remotePointsNew[m].rank = rrank; 7594 } 7595 for (r = 0; r < 8; ++r, ++m) { 7596 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 7597 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 7598 remotePointsNew[m].rank = rrank; 7599 } 7600 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 7601 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; 7602 remotePointsNew[m].rank = rrank; 7603 ++m; 7604 } else if ((p >= cMax) && (p < cEnd)) { 7605 /* Hybrid cells add new cells and faces */ 7606 for (r = 0; r < 4; ++r, ++m) { 7607 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7608 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7609 remotePointsNew[m].rank = rrank; 7610 } 7611 for (r = 0; r < 3; ++r, ++m) { 7612 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 7613 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; 7614 remotePointsNew[m].rank = rrank; 7615 } 7616 } 7617 break; 7618 case REFINER_SIMPLEX_TO_HEX_3D: 7619 if ((p >= vStart) && (p < vEnd)) { 7620 /* Interior vertices stay the same */ 7621 localPointsNew[m] = vStartNew + (p - vStart); 7622 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7623 remotePointsNew[m].rank = rrank; 7624 ++m; 7625 } else if ((p >= eStart) && (p < eEnd)) { 7626 /* Interior edges add new edges and vertex */ 7627 for (r = 0; r < 2; ++r, ++m) { 7628 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7629 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7630 remotePointsNew[m].rank = rrank; 7631 } 7632 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7633 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7634 remotePointsNew[m].rank = rrank; 7635 ++m; 7636 } else if ((p >= fStart) && (p < fEnd)) { 7637 /* Interior faces add new faces, edges and a vertex */ 7638 for (r = 0; r < 3; ++r, ++m) { 7639 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 7640 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 7641 remotePointsNew[m].rank = rrank; 7642 } 7643 for (r = 0; r < 3; ++r, ++m) { 7644 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 7645 remotePointsNew[m].index = reStartNew[n] + (rdepthSizeOld[n*(depth+1)+1])*2 + (rp - rfStart[n])*3 + r; 7646 remotePointsNew[m].rank = rrank; 7647 } 7648 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 7649 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + (rp - rfStart[n]); 7650 remotePointsNew[m].rank = rrank; 7651 ++m; 7652 } else if ((p >= cStart) && (p < cEnd)) { 7653 /* Interior cells add new cells, faces, edges, and a vertex */ 7654 for (r = 0; r < 4; ++r, ++m) { 7655 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 7656 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 7657 remotePointsNew[m].rank = rrank; 7658 } 7659 for (r = 0; r < 6; ++r, ++m) { 7660 localPointsNew[m] = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 7661 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*6 + r; 7662 remotePointsNew[m].rank = rrank; 7663 } 7664 for (r = 0; r < 4; ++r, ++m) { 7665 localPointsNew[m] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 7666 remotePointsNew[m].index = reStartNew[n] + rdepthSizeOld[n*(depth+1)+1]*2 + rdepthSizeOld[n*(depth+1)+depth-1]*3 + (rp - rcStart[n])*4 + r; 7667 remotePointsNew[m].rank = rrank; 7668 } 7669 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 7670 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+1] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 7671 remotePointsNew[m].rank = rrank; 7672 ++m; 7673 } 7674 break; 7675 case REFINER_HEX_3D: 7676 case REFINER_HYBRID_HEX_3D: 7677 if ((p >= vStart) && (p < vEnd)) { 7678 /* Interior vertices stay the same */ 7679 localPointsNew[m] = vStartNew + (p - vStart); 7680 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 7681 remotePointsNew[m].rank = rrank; 7682 ++m; 7683 } else if ((p >= eStart) && (p < eMax)) { 7684 /* Interior edges add new edges and vertex */ 7685 for (r = 0; r < 2; ++r, ++m) { 7686 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 7687 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 7688 remotePointsNew[m].rank = rrank; 7689 } 7690 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 7691 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 7692 remotePointsNew[m].rank = rrank; 7693 ++m; 7694 } else if ((p >= eMax) && (p < eEnd)) { 7695 /* Hybrid edges stay the same */ 7696 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 7697 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]); 7698 remotePointsNew[m].rank = rrank; 7699 ++m; 7700 } else if ((p >= fStart) && (p < fMax)) { 7701 /* Interior faces add new faces, edges, and vertex */ 7702 for (r = 0; r < 4; ++r, ++m) { 7703 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 7704 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 7705 remotePointsNew[m].rank = rrank; 7706 } 7707 for (r = 0; r < 4; ++r, ++m) { 7708 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 7709 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 7710 remotePointsNew[m].rank = rrank; 7711 } 7712 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 7713 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 7714 remotePointsNew[m].rank = rrank; 7715 ++m; 7716 } else if ((p >= fMax) && (p < fEnd)) { 7717 /* Hybrid faces add new faces and edges */ 7718 for (r = 0; r < 2; ++r, ++m) { 7719 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 7720 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; 7721 remotePointsNew[m].rank = rrank; 7722 } 7723 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 7724 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]); 7725 remotePointsNew[m].rank = rrank; 7726 ++m; 7727 } else if ((p >= cStart) && (p < cMax)) { 7728 /* Interior cells add new cells, faces, edges, and vertex */ 7729 for (r = 0; r < 8; ++r, ++m) { 7730 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 7731 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 7732 remotePointsNew[m].rank = rrank; 7733 } 7734 for (r = 0; r < 12; ++r, ++m) { 7735 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 7736 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 7737 remotePointsNew[m].rank = rrank; 7738 } 7739 for (r = 0; r < 6; ++r, ++m) { 7740 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 7741 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; 7742 remotePointsNew[m].rank = rrank; 7743 } 7744 for (r = 0; r < 1; ++r, ++m) { 7745 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 7746 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 7747 remotePointsNew[m].rank = rrank; 7748 } 7749 } else if ((p >= cMax) && (p < cEnd)) { 7750 /* Hybrid cells add new cells, faces, and edges */ 7751 for (r = 0; r < 4; ++r, ++m) { 7752 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 7753 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 7754 remotePointsNew[m].rank = rrank; 7755 } 7756 for (r = 0; r < 4; ++r, ++m) { 7757 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 7758 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; 7759 remotePointsNew[m].rank = rrank; 7760 } 7761 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 7762 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]); 7763 remotePointsNew[m].rank = rrank; 7764 ++m; 7765 } 7766 break; 7767 default: 7768 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7769 } 7770 } 7771 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 7772 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 7773 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 7774 { 7775 PetscSFNode *rp, *rtmp; 7776 PetscInt *lp, *idx, *ltmp, i; 7777 7778 /* SF needs sorted leaves to correct calculate Gather */ 7779 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 7780 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 7781 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 7782 for (i = 0; i < numLeavesNew; ++i) { 7783 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); 7784 idx[i] = i; 7785 } 7786 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 7787 for (i = 0; i < numLeavesNew; ++i) { 7788 lp[i] = localPointsNew[idx[i]]; 7789 rp[i] = remotePointsNew[idx[i]]; 7790 } 7791 ltmp = localPointsNew; 7792 localPointsNew = lp; 7793 rtmp = remotePointsNew; 7794 remotePointsNew = rp; 7795 ierr = PetscFree(idx);CHKERRQ(ierr); 7796 ierr = PetscFree(ltmp);CHKERRQ(ierr); 7797 ierr = PetscFree(rtmp);CHKERRQ(ierr); 7798 } 7799 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 7800 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 7801 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 7802 PetscFunctionReturn(0); 7803 } 7804 7805 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 7806 { 7807 PetscInt numLabels, l; 7808 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 7809 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 7810 PetscErrorCode ierr; 7811 7812 PetscFunctionBegin; 7813 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 7814 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 7815 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 7816 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 7817 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 7818 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 7819 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 7820 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 7821 switch (refiner) { 7822 case REFINER_NOOP: 7823 case REFINER_SIMPLEX_1D: 7824 case REFINER_SIMPLEX_2D: 7825 case REFINER_SIMPLEX_TO_HEX_2D: 7826 case REFINER_HEX_2D: 7827 case REFINER_SIMPLEX_3D: 7828 case REFINER_HEX_3D: 7829 case REFINER_SIMPLEX_TO_HEX_3D: 7830 break; 7831 case REFINER_HYBRID_SIMPLEX_3D: 7832 case REFINER_HYBRID_HEX_3D: 7833 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 7834 case REFINER_HYBRID_SIMPLEX_2D: 7835 case REFINER_HYBRID_HEX_2D: 7836 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 7837 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 7838 break; 7839 default: 7840 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 7841 } 7842 for (l = 0; l < numLabels; ++l) { 7843 DMLabel label, labelNew; 7844 const char *lname; 7845 PetscBool isDepth; 7846 IS valueIS; 7847 const PetscInt *values; 7848 PetscInt defVal; 7849 PetscInt numValues, val; 7850 7851 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 7852 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 7853 if (isDepth) continue; 7854 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 7855 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 7856 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 7857 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 7858 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 7859 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 7860 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 7861 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 7862 for (val = 0; val < numValues; ++val) { 7863 IS pointIS; 7864 const PetscInt *points; 7865 PetscInt numPoints, n; 7866 7867 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 7868 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 7869 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 7870 /* Ensure refined label is created with same number of strata as 7871 * original (even if no entries here). */ 7872 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 7873 for (n = 0; n < numPoints; ++n) { 7874 const PetscInt p = points[n]; 7875 switch (refiner) { 7876 case REFINER_SIMPLEX_1D: 7877 if ((p >= vStart) && (p < vEnd)) { 7878 /* Old vertices stay the same */ 7879 newp = vStartNew + (p - vStart); 7880 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7881 } else if ((p >= cStart) && (p < cEnd)) { 7882 /* Old cells add new cells and vertex */ 7883 newp = vStartNew + (vEnd - vStart) + (p - cStart); 7884 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7885 for (r = 0; r < 2; ++r) { 7886 newp = cStartNew + (p - cStart)*2 + r; 7887 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7888 } 7889 } 7890 break; 7891 case REFINER_SIMPLEX_2D: 7892 if ((p >= vStart) && (p < vEnd)) { 7893 /* Old vertices stay the same */ 7894 newp = vStartNew + (p - vStart); 7895 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7896 } else if ((p >= fStart) && (p < fEnd)) { 7897 /* Old faces add new faces and vertex */ 7898 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7899 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7900 for (r = 0; r < 2; ++r) { 7901 newp = fStartNew + (p - fStart)*2 + r; 7902 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7903 } 7904 } else if ((p >= cStart) && (p < cEnd)) { 7905 /* Old cells add new cells and interior faces */ 7906 for (r = 0; r < 4; ++r) { 7907 newp = cStartNew + (p - cStart)*4 + r; 7908 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7909 } 7910 for (r = 0; r < 3; ++r) { 7911 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7912 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7913 } 7914 } 7915 break; 7916 case REFINER_SIMPLEX_TO_HEX_2D: 7917 if ((p >= vStart) && (p < vEnd)) { 7918 /* Old vertices stay the same */ 7919 newp = vStartNew + (p - vStart); 7920 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7921 } else if ((p >= fStart) && (p < fEnd)) { 7922 /* Old faces add new faces and vertex */ 7923 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7924 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7925 for (r = 0; r < 2; ++r) { 7926 newp = fStartNew + (p - fStart)*2 + r; 7927 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7928 } 7929 } else if ((p >= cStart) && (p < cEnd)) { 7930 /* Old cells add new cells, interior faces, and a vertex */ 7931 for (r = 0; r < 3; ++r) { 7932 newp = cStartNew + (p - cStart)*3 + r; 7933 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7934 } 7935 for (r = 0; r < 3; ++r) { 7936 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7937 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7938 } 7939 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 7940 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7941 } 7942 break; 7943 case REFINER_HEX_2D: 7944 if ((p >= vStart) && (p < vEnd)) { 7945 /* Old vertices stay the same */ 7946 newp = vStartNew + (p - vStart); 7947 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7948 } else if ((p >= fStart) && (p < fEnd)) { 7949 /* Old faces add new faces and vertex */ 7950 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7951 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7952 for (r = 0; r < 2; ++r) { 7953 newp = fStartNew + (p - fStart)*2 + r; 7954 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7955 } 7956 } else if ((p >= cStart) && (p < cEnd)) { 7957 /* Old cells add new cells and interior faces and vertex */ 7958 for (r = 0; r < 4; ++r) { 7959 newp = cStartNew + (p - cStart)*4 + r; 7960 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7961 } 7962 for (r = 0; r < 4; ++r) { 7963 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 7964 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7965 } 7966 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 7967 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7968 } 7969 break; 7970 case REFINER_HYBRID_SIMPLEX_2D: 7971 if ((p >= vStart) && (p < vEnd)) { 7972 /* Old vertices stay the same */ 7973 newp = vStartNew + (p - vStart); 7974 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7975 } else if ((p >= fStart) && (p < fMax)) { 7976 /* Old interior faces add new faces and vertex */ 7977 newp = vStartNew + (vEnd - vStart) + (p - fStart); 7978 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7979 for (r = 0; r < 2; ++r) { 7980 newp = fStartNew + (p - fStart)*2 + r; 7981 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7982 } 7983 } else if ((p >= fMax) && (p < fEnd)) { 7984 /* Old hybrid faces stay the same */ 7985 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 7986 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7987 } else if ((p >= cStart) && (p < cMax)) { 7988 /* Old interior cells add new cells and interior faces */ 7989 for (r = 0; r < 4; ++r) { 7990 newp = cStartNew + (p - cStart)*4 + r; 7991 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7992 } 7993 for (r = 0; r < 3; ++r) { 7994 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 7995 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 7996 } 7997 } else if ((p >= cMax) && (p < cEnd)) { 7998 /* Old hybrid cells add new cells and hybrid face */ 7999 for (r = 0; r < 2; ++r) { 8000 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 8001 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8002 } 8003 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 8004 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8005 } 8006 break; 8007 case REFINER_HYBRID_HEX_2D: 8008 if ((p >= vStart) && (p < vEnd)) { 8009 /* Old vertices stay the same */ 8010 newp = vStartNew + (p - vStart); 8011 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8012 } else if ((p >= fStart) && (p < fMax)) { 8013 /* Old interior faces add new faces and vertex */ 8014 newp = vStartNew + (vEnd - vStart) + (p - fStart); 8015 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8016 for (r = 0; r < 2; ++r) { 8017 newp = fStartNew + (p - fStart)*2 + r; 8018 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8019 } 8020 } else if ((p >= fMax) && (p < fEnd)) { 8021 /* Old hybrid faces stay the same */ 8022 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 8023 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8024 } else if ((p >= cStart) && (p < cMax)) { 8025 /* Old interior cells add new cells, interior faces, and vertex */ 8026 for (r = 0; r < 4; ++r) { 8027 newp = cStartNew + (p - cStart)*4 + r; 8028 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8029 } 8030 for (r = 0; r < 4; ++r) { 8031 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 8032 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8033 } 8034 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 8035 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8036 } else if ((p >= cMax) && (p < cEnd)) { 8037 /* Old hybrid cells add new cells and hybrid face */ 8038 for (r = 0; r < 2; ++r) { 8039 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 8040 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8041 } 8042 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 8043 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8044 } 8045 break; 8046 case REFINER_SIMPLEX_3D: 8047 if ((p >= vStart) && (p < vEnd)) { 8048 /* Old vertices stay the same */ 8049 newp = vStartNew + (p - vStart); 8050 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8051 } else if ((p >= eStart) && (p < eEnd)) { 8052 /* Old edges add new edges and vertex */ 8053 for (r = 0; r < 2; ++r) { 8054 newp = eStartNew + (p - eStart)*2 + r; 8055 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8056 } 8057 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8058 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8059 } else if ((p >= fStart) && (p < fEnd)) { 8060 /* Old faces add new faces and edges */ 8061 for (r = 0; r < 4; ++r) { 8062 newp = fStartNew + (p - fStart)*4 + r; 8063 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8064 } 8065 for (r = 0; r < 3; ++r) { 8066 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 8067 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8068 } 8069 } else if ((p >= cStart) && (p < cEnd)) { 8070 /* Old cells add new cells and interior faces and edges */ 8071 for (r = 0; r < 8; ++r) { 8072 newp = cStartNew + (p - cStart)*8 + r; 8073 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8074 } 8075 for (r = 0; r < 8; ++r) { 8076 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 8077 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8078 } 8079 for (r = 0; r < 1; ++r) { 8080 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 8081 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8082 } 8083 } 8084 break; 8085 case REFINER_SIMPLEX_TO_HEX_3D: 8086 if ((p >= vStart) && (p < vEnd)) { 8087 /* Old vertices stay the same */ 8088 newp = vStartNew + (p - vStart); 8089 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8090 } else if ((p >= eStart) && (p < eEnd)) { 8091 /* Old edges add new edges and vertex */ 8092 for (r = 0; r < 2; ++r) { 8093 newp = eStartNew + (p - eStart)*2 + r; 8094 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8095 } 8096 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8097 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8098 } else if ((p >= fStart) && (p < fEnd)) { 8099 /* Old faces add new faces, edges and a vertex */ 8100 for (r = 0; r < 3; ++r) { 8101 newp = fStartNew + (p - fStart)*3 + r; 8102 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8103 } 8104 for (r = 0; r < 3; ++r) { 8105 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 8106 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8107 } 8108 } else if ((p >= cStart) && (p < cEnd)) { 8109 /* Old cells add new cells and interior faces and edges and a vertex */ 8110 for (r = 0; r < 4; ++r) { 8111 newp = cStartNew + (p - cStart)*4 + r; 8112 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8113 } 8114 for (r = 0; r < 6; ++r) { 8115 newp = fStartNew + (fEnd - fStart)*3 + (p - cStart)*6 + r; 8116 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8117 } 8118 for (r = 0; r < 4; ++r) { 8119 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*4 + r; 8120 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8121 } 8122 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + p - cStart; 8123 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8124 } 8125 break; 8126 case REFINER_HYBRID_SIMPLEX_3D: 8127 if ((p >= vStart) && (p < vEnd)) { 8128 /* Interior vertices stay the same */ 8129 newp = vStartNew + (p - vStart); 8130 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8131 } else if ((p >= eStart) && (p < eMax)) { 8132 /* Interior edges add new edges and vertex */ 8133 for (r = 0; r < 2; ++r) { 8134 newp = eStartNew + (p - eStart)*2 + r; 8135 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8136 } 8137 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8138 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8139 } else if ((p >= eMax) && (p < eEnd)) { 8140 /* Hybrid edges stay the same */ 8141 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 8142 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8143 } else if ((p >= fStart) && (p < fMax)) { 8144 /* Interior faces add new faces and edges */ 8145 for (r = 0; r < 4; ++r) { 8146 newp = fStartNew + (p - fStart)*4 + r; 8147 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8148 } 8149 for (r = 0; r < 3; ++r) { 8150 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 8151 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8152 } 8153 } else if ((p >= fMax) && (p < fEnd)) { 8154 /* Hybrid faces add new faces and edges */ 8155 for (r = 0; r < 2; ++r) { 8156 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 8157 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8158 } 8159 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 8160 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8161 } else if ((p >= cStart) && (p < cMax)) { 8162 /* Interior cells add new cells, faces, and edges */ 8163 for (r = 0; r < 8; ++r) { 8164 newp = cStartNew + (p - cStart)*8 + r; 8165 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8166 } 8167 for (r = 0; r < 8; ++r) { 8168 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 8169 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8170 } 8171 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 8172 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8173 } else if ((p >= cMax) && (p < cEnd)) { 8174 /* Hybrid cells add new cells and faces */ 8175 for (r = 0; r < 4; ++r) { 8176 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 8177 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8178 } 8179 for (r = 0; r < 3; ++r) { 8180 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 8181 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8182 } 8183 } 8184 break; 8185 case REFINER_HEX_3D: 8186 if ((p >= vStart) && (p < vEnd)) { 8187 /* Old vertices stay the same */ 8188 newp = vStartNew + (p - vStart); 8189 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8190 } else if ((p >= eStart) && (p < eEnd)) { 8191 /* Old edges add new edges and vertex */ 8192 for (r = 0; r < 2; ++r) { 8193 newp = eStartNew + (p - eStart)*2 + r; 8194 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8195 } 8196 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8197 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8198 } else if ((p >= fStart) && (p < fEnd)) { 8199 /* Old faces add new faces, edges, and vertex */ 8200 for (r = 0; r < 4; ++r) { 8201 newp = fStartNew + (p - fStart)*4 + r; 8202 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8203 } 8204 for (r = 0; r < 4; ++r) { 8205 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 8206 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8207 } 8208 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 8209 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8210 } else if ((p >= cStart) && (p < cEnd)) { 8211 /* Old cells add new cells, faces, edges, and vertex */ 8212 for (r = 0; r < 8; ++r) { 8213 newp = cStartNew + (p - cStart)*8 + r; 8214 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8215 } 8216 for (r = 0; r < 12; ++r) { 8217 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 8218 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8219 } 8220 for (r = 0; r < 6; ++r) { 8221 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 8222 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8223 } 8224 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 8225 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8226 } 8227 break; 8228 case REFINER_HYBRID_HEX_3D: 8229 if ((p >= vStart) && (p < vEnd)) { 8230 /* Interior vertices stay the same */ 8231 newp = vStartNew + (p - vStart); 8232 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8233 } else if ((p >= eStart) && (p < eMax)) { 8234 /* Interior edges add new edges and vertex */ 8235 for (r = 0; r < 2; ++r) { 8236 newp = eStartNew + (p - eStart)*2 + r; 8237 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8238 } 8239 newp = vStartNew + (vEnd - vStart) + (p - eStart); 8240 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8241 } else if ((p >= eMax) && (p < eEnd)) { 8242 /* Hybrid edges stay the same */ 8243 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 8244 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8245 } else if ((p >= fStart) && (p < fMax)) { 8246 /* Interior faces add new faces, edges, and vertex */ 8247 for (r = 0; r < 4; ++r) { 8248 newp = fStartNew + (p - fStart)*4 + r; 8249 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8250 } 8251 for (r = 0; r < 4; ++r) { 8252 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 8253 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8254 } 8255 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 8256 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8257 } else if ((p >= fMax) && (p < fEnd)) { 8258 /* Hybrid faces add new faces and edges */ 8259 for (r = 0; r < 2; ++r) { 8260 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 8261 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8262 } 8263 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 8264 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8265 } else if ((p >= cStart) && (p < cMax)) { 8266 /* Interior cells add new cells, faces, edges, and vertex */ 8267 for (r = 0; r < 8; ++r) { 8268 newp = cStartNew + (p - cStart)*8 + r; 8269 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8270 } 8271 for (r = 0; r < 12; ++r) { 8272 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 8273 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8274 } 8275 for (r = 0; r < 6; ++r) { 8276 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 8277 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8278 } 8279 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 8280 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8281 } else if ((p >= cMax) && (p < cEnd)) { 8282 /* Hybrid cells add new cells, faces, and edges */ 8283 for (r = 0; r < 4; ++r) { 8284 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 8285 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8286 } 8287 for (r = 0; r < 4; ++r) { 8288 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 8289 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8290 } 8291 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 8292 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 8293 } 8294 break; 8295 default: 8296 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 8297 } 8298 } 8299 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 8300 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 8301 } 8302 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 8303 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 8304 if (0) { 8305 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 8306 } 8307 } 8308 PetscFunctionReturn(0); 8309 } 8310 8311 /* This will only work for interpolated meshes */ 8312 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 8313 { 8314 DM rdm; 8315 PetscInt *depthSize; 8316 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 8317 PetscErrorCode ierr; 8318 8319 PetscFunctionBegin; 8320 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 8321 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 8322 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8323 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 8324 /* Calculate number of new points of each depth */ 8325 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8326 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 8327 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 8328 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 8329 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 8330 /* Step 1: Set chart */ 8331 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 8332 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 8333 /* Step 2: Set cone/support sizes (automatically stratifies) */ 8334 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8335 /* Step 3: Setup refined DM */ 8336 ierr = DMSetUp(rdm);CHKERRQ(ierr); 8337 /* Step 4: Set cones and supports (automatically symmetrizes) */ 8338 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8339 /* Step 5: Create pointSF */ 8340 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8341 /* Step 6: Create labels */ 8342 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8343 /* Step 7: Set coordinates */ 8344 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 8345 ierr = PetscFree(depthSize);CHKERRQ(ierr); 8346 8347 *dmRefined = rdm; 8348 PetscFunctionReturn(0); 8349 } 8350 8351 /*@ 8352 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 8353 8354 Input Parameter: 8355 . dm - The coarse DM 8356 8357 Output Parameter: 8358 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 8359 8360 Level: developer 8361 8362 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 8363 @*/ 8364 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 8365 { 8366 CellRefiner cellRefiner; 8367 PetscInt *depthSize, *fpoints; 8368 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8369 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 8370 PetscErrorCode ierr; 8371 8372 PetscFunctionBegin; 8373 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8374 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 8375 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8376 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 8377 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 8378 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 8379 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8380 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 8381 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 8382 switch (cellRefiner) { 8383 case REFINER_SIMPLEX_1D: 8384 case REFINER_SIMPLEX_2D: 8385 case REFINER_HYBRID_SIMPLEX_2D: 8386 case REFINER_HEX_2D: 8387 case REFINER_HYBRID_HEX_2D: 8388 case REFINER_SIMPLEX_3D: 8389 case REFINER_HYBRID_SIMPLEX_3D: 8390 case REFINER_HEX_3D: 8391 case REFINER_HYBRID_HEX_3D: 8392 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 8393 break; 8394 default: 8395 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 8396 } 8397 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 8398 ierr = PetscFree(depthSize);CHKERRQ(ierr); 8399 PetscFunctionReturn(0); 8400 } 8401 8402 /*@ 8403 DMPlexSetRefinementUniform - Set the flag for uniform refinement 8404 8405 Input Parameters: 8406 + dm - The DM 8407 - refinementUniform - The flag for uniform refinement 8408 8409 Level: developer 8410 8411 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8412 @*/ 8413 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 8414 { 8415 DM_Plex *mesh = (DM_Plex*) dm->data; 8416 8417 PetscFunctionBegin; 8418 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8419 mesh->refinementUniform = refinementUniform; 8420 PetscFunctionReturn(0); 8421 } 8422 8423 /*@ 8424 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 8425 8426 Input Parameter: 8427 . dm - The DM 8428 8429 Output Parameter: 8430 . refinementUniform - The flag for uniform refinement 8431 8432 Level: developer 8433 8434 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8435 @*/ 8436 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 8437 { 8438 DM_Plex *mesh = (DM_Plex*) dm->data; 8439 8440 PetscFunctionBegin; 8441 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8442 PetscValidPointer(refinementUniform, 2); 8443 *refinementUniform = mesh->refinementUniform; 8444 PetscFunctionReturn(0); 8445 } 8446 8447 /*@ 8448 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 8449 8450 Input Parameters: 8451 + dm - The DM 8452 - refinementLimit - The maximum cell volume in the refined mesh 8453 8454 Level: developer 8455 8456 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 8457 @*/ 8458 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 8459 { 8460 DM_Plex *mesh = (DM_Plex*) dm->data; 8461 8462 PetscFunctionBegin; 8463 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8464 mesh->refinementLimit = refinementLimit; 8465 PetscFunctionReturn(0); 8466 } 8467 8468 /*@ 8469 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 8470 8471 Input Parameter: 8472 . dm - The DM 8473 8474 Output Parameter: 8475 . refinementLimit - The maximum cell volume in the refined mesh 8476 8477 Level: developer 8478 8479 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 8480 @*/ 8481 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 8482 { 8483 DM_Plex *mesh = (DM_Plex*) dm->data; 8484 8485 PetscFunctionBegin; 8486 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8487 PetscValidPointer(refinementLimit, 2); 8488 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 8489 *refinementLimit = mesh->refinementLimit; 8490 PetscFunctionReturn(0); 8491 } 8492 8493 /*@ 8494 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 8495 8496 Input Parameters: 8497 + dm - The DM 8498 - refinementFunc - Function giving the maximum cell volume in the refined mesh 8499 8500 Note: The calling sequence is refinementFunc(coords, limit) 8501 $ coords - Coordinates of the current point, usually a cell centroid 8502 $ limit - The maximum cell volume for a cell containing this point 8503 8504 Level: developer 8505 8506 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8507 @*/ 8508 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 8509 { 8510 DM_Plex *mesh = (DM_Plex*) dm->data; 8511 8512 PetscFunctionBegin; 8513 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8514 mesh->refinementFunc = refinementFunc; 8515 PetscFunctionReturn(0); 8516 } 8517 8518 /*@ 8519 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 8520 8521 Input Parameter: 8522 . dm - The DM 8523 8524 Output Parameter: 8525 . refinementFunc - Function giving the maximum cell volume in the refined mesh 8526 8527 Note: The calling sequence is refinementFunc(coords, limit) 8528 $ coords - Coordinates of the current point, usually a cell centroid 8529 $ limit - The maximum cell volume for a cell containing this point 8530 8531 Level: developer 8532 8533 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 8534 @*/ 8535 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 8536 { 8537 DM_Plex *mesh = (DM_Plex*) dm->data; 8538 8539 PetscFunctionBegin; 8540 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8541 PetscValidPointer(refinementFunc, 2); 8542 *refinementFunc = mesh->refinementFunc; 8543 PetscFunctionReturn(0); 8544 } 8545 8546 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 8547 { 8548 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 8549 PetscErrorCode ierr; 8550 8551 PetscFunctionBegin; 8552 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8553 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8554 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 8555 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 8556 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 8557 switch (dim) { 8558 case 1: 8559 switch (coneSize) { 8560 case 2: 8561 *cellRefiner = REFINER_SIMPLEX_1D; 8562 break; 8563 default: 8564 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8565 } 8566 break; 8567 case 2: 8568 switch (coneSize) { 8569 case 3: 8570 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 8571 else *cellRefiner = REFINER_SIMPLEX_2D; 8572 break; 8573 case 4: 8574 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 8575 else *cellRefiner = REFINER_HEX_2D; 8576 break; 8577 default: 8578 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8579 } 8580 break; 8581 case 3: 8582 switch (coneSize) { 8583 case 4: 8584 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 8585 else *cellRefiner = REFINER_SIMPLEX_3D; 8586 break; 8587 case 6: 8588 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 8589 else *cellRefiner = REFINER_HEX_3D; 8590 break; 8591 default: 8592 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 8593 } 8594 break; 8595 default: 8596 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 8597 } 8598 PetscFunctionReturn(0); 8599 } 8600 8601 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 8602 { 8603 PetscBool isUniform; 8604 PetscErrorCode ierr; 8605 8606 PetscFunctionBegin; 8607 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 8608 if (isUniform) { 8609 CellRefiner cellRefiner; 8610 PetscBool localized; 8611 8612 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 8613 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 8614 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 8615 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 8616 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 8617 } else { 8618 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 8619 } 8620 PetscFunctionReturn(0); 8621 } 8622 8623 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 8624 { 8625 DM cdm = dm; 8626 PetscInt r; 8627 PetscBool isUniform, localized; 8628 PetscErrorCode ierr; 8629 8630 PetscFunctionBegin; 8631 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 8632 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 8633 if (isUniform) { 8634 for (r = 0; r < nlevels; ++r) { 8635 CellRefiner cellRefiner; 8636 8637 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 8638 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 8639 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 8640 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 8641 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 8642 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 8643 cdm = dmRefined[r]; 8644 } 8645 } else { 8646 for (r = 0; r < nlevels; ++r) { 8647 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 8648 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 8649 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 8650 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 8651 cdm = dmRefined[r]; 8652 } 8653 } 8654 PetscFunctionReturn(0); 8655 } 8656