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_HYBRID_SIMPLEX_TO_HEX_2D: 255 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 256 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 257 depthSize[1] = 2*(fEnd - fStart) + 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every face is split into 2 faces and 3 faces are added for each cell. 4 for each hybrid cell */ 258 depthSize[2] = 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every cell split into 3 cells, hybrid cells split in 4 */ 259 break; 260 case REFINER_HEX_2D: 261 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 262 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 263 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 264 break; 265 case REFINER_HYBRID_HEX_2D: 266 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 267 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 268 /* Quadrilateral */ 269 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 270 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 271 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 272 /* Segment Prisms */ 273 depthSize[0] += 0; /* No hybrid vertices */ 274 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 275 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 276 break; 277 case REFINER_SIMPLEX_3D: 278 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 279 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 */ 280 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 281 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 282 break; 283 case REFINER_HYBRID_SIMPLEX_3D: 284 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 285 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 286 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 287 /* Tetrahedra */ 288 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 289 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 */ 290 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 291 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 292 /* Triangular Prisms */ 293 depthSize[0] += 0; /* No hybrid vertices */ 294 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 295 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 296 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 297 break; 298 case REFINER_SIMPLEX_TO_HEX_3D: 299 depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */ 300 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 */ 301 depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */ 302 depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 303 break; 304 case REFINER_HYBRID_SIMPLEX_TO_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 /* Tetrahedra */ 309 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every interior edge, face and cell */ 310 depthSize[1] = 2*(eMax - eStart) + 3*(fMax - fStart) + 4*(cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 4 edges for each interior cell */ 311 depthSize[2] = 3*(fMax - fStart) + 6*(cMax - cStart); /* Every interior face split into 3 faces, 6 faces added for each interior cell */ 312 depthSize[3] = 4*(cMax - cStart); /* Every interior cell split into 8 cells */ 313 /* Triangular 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 cell */ 316 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 317 depthSize[3] += 3*(cEnd - cMax); /* Every hybrid cell split into 3 cells */ 318 break; 319 case REFINER_HEX_3D: 320 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 321 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 */ 322 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 323 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 324 break; 325 case REFINER_HYBRID_HEX_3D: 326 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 327 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 328 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 329 /* Hexahedra */ 330 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 331 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 */ 332 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 333 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 334 /* Quadrilateral Prisms */ 335 depthSize[0] += 0; /* No hybrid vertices */ 336 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 337 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 338 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 339 break; 340 default: 341 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 342 } 343 PetscFunctionReturn(0); 344 } 345 346 /* Return triangle edge for orientation o, if it is r for o == 0 */ 347 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 348 return (o < 0 ? 2-(o+r) : o+r)%3; 349 } 350 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 351 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 352 } 353 354 /* Return triangle subface for orientation o, if it is r for o == 0 */ 355 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 356 return (o < 0 ? 3-(o+r) : o+r)%3; 357 } 358 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 359 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 360 } 361 362 /* Return the interior edge number connecting the midpoints of the triangle edges r 363 and r+1 in the transitive closure for triangle orientation o */ 364 PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) { 365 return (o < 0 ? 1-(o+r) : o+r)%3; 366 } 367 PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) { 368 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 369 } 370 371 /* Return the interior edge number connecting the midpoint of the triangle edge r 372 (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */ 373 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) { 374 return (o < 0 ? 2-(o+r) : o+r)%3; 375 } 376 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) { 377 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 378 } 379 380 /* Return quad edge for orientation o, if it is r for o == 0 */ 381 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 382 return (o < 0 ? 3-(o+r) : o+r)%4; 383 } 384 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 385 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 386 } 387 388 /* Return quad subface for orientation o, if it is r for o == 0 */ 389 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 390 return (o < 0 ? 4-(o+r) : o+r)%4; 391 } 392 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 393 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 394 } 395 396 static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd) 397 { 398 IS cIS; 399 PetscErrorCode ierr; 400 401 PetscFunctionBegin; 402 ierr = ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);CHKERRQ(ierr); 403 ierr = DMLabelSetStratumIS(label, value, cIS);CHKERRQ(ierr); 404 ierr = ISDestroy(&cIS);CHKERRQ(ierr); 405 PetscFunctionReturn(0); 406 } 407 408 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 409 { 410 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; 411 DMLabel depthLabel; 412 PetscErrorCode ierr; 413 414 PetscFunctionBegin; 415 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 416 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 417 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 418 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 419 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 420 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 421 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 422 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 423 ierr = DMCreateLabel(rdm,"depth");CHKERRQ(ierr); 424 ierr = DMPlexGetDepthLabel(rdm,&depthLabel);CHKERRQ(ierr); 425 ierr = DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);CHKERRQ(ierr); 426 if (depth > 2) ierr = DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);CHKERRQ(ierr); 427 if (depth > 1) ierr = DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);CHKERRQ(ierr); 428 if (depth > 0) ierr = DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);CHKERRQ(ierr); 429 { 430 DM_Plex *plex = (DM_Plex *) rdm->data; 431 ierr = DMLabelGetState(depthLabel, &plex->depthState);CHKERRQ(ierr); 432 } 433 if (!refiner) PetscFunctionReturn(0); 434 switch (refiner) { 435 case REFINER_SIMPLEX_1D: 436 /* All cells have 2 vertices */ 437 for (c = cStart; c < cEnd; ++c) { 438 for (r = 0; r < 2; ++r) { 439 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 440 441 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 442 } 443 } 444 /* Old vertices have identical supports */ 445 for (v = vStart; v < vEnd; ++v) { 446 const PetscInt newp = vStartNew + (v - vStart); 447 PetscInt size; 448 449 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 450 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 451 } 452 /* Cell vertices have support 2 */ 453 for (c = cStart; c < cEnd; ++c) { 454 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 455 456 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 457 } 458 break; 459 case REFINER_SIMPLEX_2D: 460 /* All cells have 3 faces */ 461 for (c = cStart; c < cEnd; ++c) { 462 for (r = 0; r < 4; ++r) { 463 const PetscInt newp = (c - cStart)*4 + r; 464 465 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 466 } 467 } 468 /* Split faces have 2 vertices and the same cells as the parent */ 469 for (f = fStart; f < fEnd; ++f) { 470 for (r = 0; r < 2; ++r) { 471 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 472 PetscInt size; 473 474 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 475 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 476 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 477 } 478 } 479 /* Interior faces have 2 vertices and 2 cells */ 480 for (c = cStart; c < cEnd; ++c) { 481 for (r = 0; r < 3; ++r) { 482 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 483 484 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 485 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 486 } 487 } 488 /* Old vertices have identical supports */ 489 for (v = vStart; v < vEnd; ++v) { 490 const PetscInt newp = vStartNew + (v - vStart); 491 PetscInt size; 492 493 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 494 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 495 } 496 /* Face vertices have 2 + cells*2 supports */ 497 for (f = fStart; f < fEnd; ++f) { 498 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 499 PetscInt size; 500 501 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 502 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 503 } 504 break; 505 case REFINER_SIMPLEX_TO_HEX_2D: 506 /* All cells have 4 faces */ 507 for (c = cStart; c < cEnd; ++c) { 508 for (r = 0; r < 3; ++r) { 509 const PetscInt newp = (c - cStart)*3 + r; 510 511 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 512 } 513 } 514 /* Split faces have 2 vertices and the same cells as the parent */ 515 for (f = fStart; f < fEnd; ++f) { 516 for (r = 0; r < 2; ++r) { 517 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 518 PetscInt size; 519 520 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 521 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 522 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 523 } 524 } 525 /* Interior faces have 2 vertices and 2 cells */ 526 for (c = cStart; c < cEnd; ++c) { 527 for (r = 0; r < 3; ++r) { 528 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 529 530 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 531 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 532 } 533 } 534 /* Old vertices have identical supports */ 535 for (v = vStart; v < vEnd; ++v) { 536 const PetscInt newp = vStartNew + (v - vStart); 537 PetscInt size; 538 539 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 540 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 541 } 542 /* Split-face vertices have cells + 2 supports */ 543 for (f = fStart; f < fEnd; ++f) { 544 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 545 PetscInt size; 546 547 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 548 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 549 } 550 /* Interior vertices have 3 supports */ 551 for (c = cStart; c < cEnd; ++c) { 552 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 553 554 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 555 } 556 break; 557 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 558 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 559 /* the mesh is no longer hybrid */ 560 cMax = PetscMin(cEnd, cMax); 561 /* All cells have 4 faces */ 562 for (c = cStart; c < cMax; ++c) { 563 for (r = 0; r < 3; ++r) { 564 const PetscInt newp = (c - cStart)*3 + r; 565 566 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 567 } 568 } 569 for (c = cMax; c < cEnd; ++c) { 570 for (r = 0; r < 4; ++r) { 571 const PetscInt newp = (cMax - cStart)*3 + (c - cMax)*4 + r; 572 573 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 574 } 575 } 576 /* Split faces have 2 vertices and the same cells as the parent */ 577 for (f = fStart; f < fEnd; ++f) { 578 for (r = 0; r < 2; ++r) { 579 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 580 PetscInt size; 581 582 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 583 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 584 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 585 } 586 } 587 /* Interior faces have 2 vertices and 2 cells */ 588 for (c = cStart; c < cMax; ++c) { 589 for (r = 0; r < 3; ++r) { 590 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 591 592 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 593 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 594 } 595 } 596 /* Hybrid interior faces have 2 vertices and 2 cells */ 597 for (c = cMax; c < cEnd; ++c) { 598 for (r = 0; r < 4; ++r) { 599 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 600 601 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 602 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 603 } 604 } 605 /* Old vertices have identical supports */ 606 for (v = vStart; v < vEnd; ++v) { 607 const PetscInt newp = vStartNew + (v - vStart); 608 PetscInt size; 609 610 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 611 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 612 } 613 /* Split-face vertices have cells + 2 supports */ 614 for (f = fStart; f < fEnd; ++f) { 615 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 616 PetscInt size; 617 618 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 619 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 620 } 621 /* Interior vertices have 3 supports */ 622 for (c = cStart; c < cMax; ++c) { 623 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 624 625 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 626 } 627 /* Hybrid interior vertices have 4 supports */ 628 for (c = cMax; c < cEnd; ++c) { 629 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 630 631 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 632 } 633 break; 634 case REFINER_HEX_2D: 635 /* All cells have 4 faces */ 636 for (c = cStart; c < cEnd; ++c) { 637 for (r = 0; r < 4; ++r) { 638 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 639 640 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 641 } 642 } 643 /* Split faces have 2 vertices and the same cells as the parent */ 644 for (f = fStart; f < fEnd; ++f) { 645 for (r = 0; r < 2; ++r) { 646 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 647 PetscInt size; 648 649 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 650 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 651 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 652 } 653 } 654 /* Interior faces have 2 vertices and 2 cells */ 655 for (c = cStart; c < cEnd; ++c) { 656 for (r = 0; r < 4; ++r) { 657 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 658 659 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 660 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 661 } 662 } 663 /* Old vertices have identical supports */ 664 for (v = vStart; v < vEnd; ++v) { 665 const PetscInt newp = vStartNew + (v - vStart); 666 PetscInt size; 667 668 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 669 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 670 } 671 /* Face vertices have 2 + cells supports */ 672 for (f = fStart; f < fEnd; ++f) { 673 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 674 PetscInt size; 675 676 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 677 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 678 } 679 /* Cell vertices have 4 supports */ 680 for (c = cStart; c < cEnd; ++c) { 681 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 682 683 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 684 } 685 break; 686 case REFINER_HYBRID_SIMPLEX_2D: 687 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 688 cMax = PetscMin(cEnd, cMax); 689 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 690 fMax = PetscMin(fEnd, fMax); 691 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 692 /* Interior cells have 3 faces */ 693 for (c = cStart; c < cMax; ++c) { 694 for (r = 0; r < 4; ++r) { 695 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 696 697 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 698 } 699 } 700 /* Hybrid cells have 4 faces */ 701 for (c = cMax; c < cEnd; ++c) { 702 for (r = 0; r < 2; ++r) { 703 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 704 705 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 706 } 707 } 708 /* Interior split faces have 2 vertices and the same cells as the parent */ 709 for (f = fStart; f < fMax; ++f) { 710 for (r = 0; r < 2; ++r) { 711 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 712 PetscInt size; 713 714 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 715 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 716 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 717 } 718 } 719 /* Interior cell faces have 2 vertices and 2 cells */ 720 for (c = cStart; c < cMax; ++c) { 721 for (r = 0; r < 3; ++r) { 722 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 723 724 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 725 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 726 } 727 } 728 /* Hybrid faces have 2 vertices and the same cells */ 729 for (f = fMax; f < fEnd; ++f) { 730 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 731 PetscInt size; 732 733 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 734 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 735 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 736 } 737 /* Hybrid cell faces have 2 vertices and 2 cells */ 738 for (c = cMax; c < cEnd; ++c) { 739 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 740 741 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 742 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 743 } 744 /* Old vertices have identical supports */ 745 for (v = vStart; v < vEnd; ++v) { 746 const PetscInt newp = vStartNew + (v - vStart); 747 PetscInt size; 748 749 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 750 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 751 } 752 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 753 for (f = fStart; f < fMax; ++f) { 754 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 755 const PetscInt *support; 756 PetscInt size, newSize = 2, s; 757 758 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 759 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 760 for (s = 0; s < size; ++s) { 761 if (support[s] >= cMax) newSize += 1; 762 else newSize += 2; 763 } 764 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 765 } 766 break; 767 case REFINER_HYBRID_HEX_2D: 768 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 769 cMax = PetscMin(cEnd, cMax); 770 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 771 fMax = PetscMin(fEnd, fMax); 772 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 773 /* Interior cells have 4 faces */ 774 for (c = cStart; c < cMax; ++c) { 775 for (r = 0; r < 4; ++r) { 776 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 777 778 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 779 } 780 } 781 /* Hybrid cells have 4 faces */ 782 for (c = cMax; c < cEnd; ++c) { 783 for (r = 0; r < 2; ++r) { 784 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 785 786 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 787 } 788 } 789 /* Interior split faces have 2 vertices and the same cells as the parent */ 790 for (f = fStart; f < fMax; ++f) { 791 for (r = 0; r < 2; ++r) { 792 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 793 PetscInt size; 794 795 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 796 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 797 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 798 } 799 } 800 /* Interior cell faces have 2 vertices and 2 cells */ 801 for (c = cStart; c < cMax; ++c) { 802 for (r = 0; r < 4; ++r) { 803 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 804 805 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 806 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 807 } 808 } 809 /* Hybrid faces have 2 vertices and the same cells */ 810 for (f = fMax; f < fEnd; ++f) { 811 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 812 PetscInt size; 813 814 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 815 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 816 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 817 } 818 /* Hybrid cell faces have 2 vertices and 2 cells */ 819 for (c = cMax; c < cEnd; ++c) { 820 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 821 822 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 823 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 824 } 825 /* Old vertices have identical supports */ 826 for (v = vStart; v < vEnd; ++v) { 827 const PetscInt newp = vStartNew + (v - vStart); 828 PetscInt size; 829 830 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 831 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 832 } 833 /* Face vertices have 2 + cells supports */ 834 for (f = fStart; f < fMax; ++f) { 835 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 836 PetscInt size; 837 838 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 839 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 840 } 841 /* Cell vertices have 4 supports */ 842 for (c = cStart; c < cMax; ++c) { 843 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 844 845 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 846 } 847 break; 848 case REFINER_SIMPLEX_3D: 849 /* All cells have 4 faces */ 850 for (c = cStart; c < cEnd; ++c) { 851 for (r = 0; r < 8; ++r) { 852 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 853 854 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 855 } 856 } 857 /* Split faces have 3 edges and the same cells as the parent */ 858 for (f = fStart; f < fEnd; ++f) { 859 for (r = 0; r < 4; ++r) { 860 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 861 PetscInt size; 862 863 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 864 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 865 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 866 } 867 } 868 /* Interior cell faces have 3 edges and 2 cells */ 869 for (c = cStart; c < cEnd; ++c) { 870 for (r = 0; r < 8; ++r) { 871 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 872 873 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 874 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 875 } 876 } 877 /* Split edges have 2 vertices and the same faces */ 878 for (e = eStart; e < eEnd; ++e) { 879 for (r = 0; r < 2; ++r) { 880 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 881 PetscInt size; 882 883 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 884 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 885 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 886 } 887 } 888 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 889 for (f = fStart; f < fEnd; ++f) { 890 for (r = 0; r < 3; ++r) { 891 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 892 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 893 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 894 895 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 896 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 897 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 898 for (s = 0; s < supportSize; ++s) { 899 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 900 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 901 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 902 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 903 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 904 er = GetTriMidEdgeInverse_Static(ornt[c], r); 905 if (er == eint[c]) { 906 intFaces += 1; 907 } else { 908 intFaces += 2; 909 } 910 } 911 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 912 } 913 } 914 /* Interior cell edges have 2 vertices and 4 faces */ 915 for (c = cStart; c < cEnd; ++c) { 916 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 917 918 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 919 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 920 } 921 /* Old vertices have identical supports */ 922 for (v = vStart; v < vEnd; ++v) { 923 const PetscInt newp = vStartNew + (v - vStart); 924 PetscInt size; 925 926 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 927 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 928 } 929 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 930 for (e = eStart; e < eEnd; ++e) { 931 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 932 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 933 934 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 935 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 936 for (s = 0; s < starSize*2; s += 2) { 937 const PetscInt *cone, *ornt; 938 PetscInt e01, e23; 939 940 if ((star[s] >= cStart) && (star[s] < cEnd)) { 941 /* Check edge 0-1 */ 942 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 943 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 944 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 945 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 946 /* Check edge 2-3 */ 947 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 948 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 949 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 950 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 951 if ((e01 == e) || (e23 == e)) ++cellSize; 952 } 953 } 954 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 955 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 956 } 957 break; 958 case REFINER_HYBRID_SIMPLEX_3D: 959 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 960 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 961 /* Interior cells have 4 faces */ 962 for (c = cStart; c < cMax; ++c) { 963 for (r = 0; r < 8; ++r) { 964 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 965 966 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 967 } 968 } 969 /* Hybrid cells have 5 faces */ 970 for (c = cMax; c < cEnd; ++c) { 971 for (r = 0; r < 4; ++r) { 972 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 973 974 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 975 } 976 } 977 /* Interior split faces have 3 edges and the same cells as the parent */ 978 for (f = fStart; f < fMax; ++f) { 979 for (r = 0; r < 4; ++r) { 980 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 981 PetscInt size; 982 983 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 984 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 985 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 986 } 987 } 988 /* Interior cell faces have 3 edges and 2 cells */ 989 for (c = cStart; c < cMax; ++c) { 990 for (r = 0; r < 8; ++r) { 991 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 992 993 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 994 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 995 } 996 } 997 /* Hybrid split faces have 4 edges and the same cells as the parent */ 998 for (f = fMax; f < fEnd; ++f) { 999 for (r = 0; r < 2; ++r) { 1000 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 1001 PetscInt size; 1002 1003 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1004 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1005 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1006 } 1007 } 1008 /* Hybrid cells faces have 4 edges and 2 cells */ 1009 for (c = cMax; c < cEnd; ++c) { 1010 for (r = 0; r < 3; ++r) { 1011 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1012 1013 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1014 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1015 } 1016 } 1017 /* Interior split edges have 2 vertices and the same faces */ 1018 for (e = eStart; e < eMax; ++e) { 1019 for (r = 0; r < 2; ++r) { 1020 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1021 PetscInt size; 1022 1023 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1024 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1025 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1026 } 1027 } 1028 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 1029 for (f = fStart; f < fMax; ++f) { 1030 for (r = 0; r < 3; ++r) { 1031 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1032 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 1033 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 1034 1035 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1036 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1037 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1038 for (s = 0; s < supportSize; ++s) { 1039 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1040 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1041 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1042 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1043 if (support[s] < cMax) { 1044 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 1045 er = GetTriMidEdgeInverse_Static(ornt[c], r); 1046 if (er == eint[c]) { 1047 intFaces += 1; 1048 } else { 1049 intFaces += 2; 1050 } 1051 } else { 1052 intFaces += 1; 1053 } 1054 } 1055 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 1056 } 1057 } 1058 /* Interior cell edges have 2 vertices and 4 faces */ 1059 for (c = cStart; c < cMax; ++c) { 1060 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 1061 1062 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1063 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1064 } 1065 /* Hybrid edges have 2 vertices and the same faces */ 1066 for (e = eMax; e < eEnd; ++e) { 1067 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 1068 PetscInt size; 1069 1070 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1071 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1072 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1073 } 1074 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 1075 for (f = fMax; f < fEnd; ++f) { 1076 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 1077 PetscInt size; 1078 1079 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1080 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1081 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 1082 } 1083 /* Interior vertices have identical supports */ 1084 for (v = vStart; v < vEnd; ++v) { 1085 const PetscInt newp = vStartNew + (v - vStart); 1086 PetscInt size; 1087 1088 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1089 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1090 } 1091 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 1092 for (e = eStart; e < eMax; ++e) { 1093 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1094 const PetscInt *support; 1095 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 1096 1097 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1098 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1099 for (s = 0; s < size; ++s) { 1100 if (support[s] < fMax) faceSize += 2; 1101 else faceSize += 1; 1102 } 1103 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1104 for (s = 0; s < starSize*2; s += 2) { 1105 const PetscInt *cone, *ornt; 1106 PetscInt e01, e23; 1107 1108 if ((star[s] >= cStart) && (star[s] < cMax)) { 1109 /* Check edge 0-1 */ 1110 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1111 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1112 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1113 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1114 /* Check edge 2-3 */ 1115 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1116 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1117 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1118 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1119 if ((e01 == e) || (e23 == e)) ++cellSize; 1120 } 1121 } 1122 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1123 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 1124 } 1125 break; 1126 case REFINER_SIMPLEX_TO_HEX_3D: 1127 /* All cells have 6 faces */ 1128 for (c = cStart; c < cEnd; ++c) { 1129 for (r = 0; r < 4; ++r) { 1130 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1131 1132 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1133 } 1134 } 1135 /* Split faces have 4 edges and the same cells as the parent */ 1136 for (f = fStart; f < fEnd; ++f) { 1137 for (r = 0; r < 3; ++r) { 1138 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1139 PetscInt size; 1140 1141 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1142 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1143 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1144 } 1145 } 1146 /* Interior cell faces have 4 edges and 2 cells */ 1147 for (c = cStart; c < cEnd; ++c) { 1148 for (r = 0; r < 6; ++r) { 1149 const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r; 1150 1151 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1152 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1153 } 1154 } 1155 /* Split edges have 2 vertices and the same faces */ 1156 for (e = eStart; e < eEnd; ++e) { 1157 for (r = 0; r < 2; ++r) { 1158 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1159 PetscInt size; 1160 1161 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1162 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1163 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1164 } 1165 } 1166 /* Face edges have 2 vertices and 2 + cell faces supports */ 1167 for (f = fStart; f < fEnd; ++f) { 1168 for (r = 0; r < 3; ++r) { 1169 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1170 PetscInt size; 1171 1172 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1173 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1174 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1175 } 1176 } 1177 /* Interior cell edges have 2 vertices and 3 faces */ 1178 for (c = cStart; c < cEnd; ++c) { 1179 for (r = 0; r < 4; ++r) { 1180 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 1181 1182 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1183 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1184 } 1185 } 1186 /* Old vertices have identical supports */ 1187 for (v = vStart; v < vEnd; ++v) { 1188 const PetscInt newp = vStartNew + (v - vStart); 1189 PetscInt size; 1190 1191 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1192 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1193 } 1194 /* Edge vertices have 2 + faces supports */ 1195 for (e = eStart; e < eEnd; ++e) { 1196 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1197 PetscInt size; 1198 1199 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1200 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1201 } 1202 /* Face vertices have 3 + cells supports */ 1203 for (f = fStart; f < fEnd; ++f) { 1204 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 1205 PetscInt size; 1206 1207 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1208 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1209 } 1210 /* Interior cell vertices have 4 supports */ 1211 for (c = cStart; c < cEnd; ++c) { 1212 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart; 1213 1214 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1215 } 1216 break; 1217 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 1218 /* the mesh is no longer hybrid */ 1219 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1220 cMax = PetscMin(cEnd, cMax); 1221 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1222 fMax = PetscMin(fEnd, fMax); 1223 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 1224 eMax = PetscMin(eEnd, eMax); 1225 /* All cells have 6 faces */ 1226 for (c = cStart; c < cMax; ++c) { 1227 for (r = 0; r < 4; ++r) { 1228 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1229 1230 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1231 } 1232 } 1233 for (c = cMax; c < cEnd; ++c) { 1234 for (r = 0; r < 3; ++r) { 1235 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + r; 1236 1237 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1238 } 1239 } 1240 /* Interior split faces have 4 edges and the same cells as the parent */ 1241 for (f = fStart; f < fMax; ++f) { 1242 for (r = 0; r < 3; ++r) { 1243 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1244 PetscInt size; 1245 1246 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1247 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1248 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1249 } 1250 } 1251 /* Interior cell faces have 4 edges and 2 cells */ 1252 for (c = cStart; c < cMax; ++c) { 1253 for (r = 0; r < 6; ++r) { 1254 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + r; 1255 1256 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1257 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1258 } 1259 } 1260 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1261 for (f = fMax; f < fEnd; ++f) { 1262 for (r = 0; r < 2; ++r) { 1263 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2 + r; 1264 PetscInt size; 1265 1266 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1267 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1268 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1269 } 1270 } 1271 /* Hybrid cell faces have 4 edges and 2 cells */ 1272 for (c = cMax; c < cEnd; ++c) { 1273 for (r = 0; r < 3; ++r) { 1274 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1275 1276 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1277 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1278 } 1279 } 1280 /* Interior split edges have 2 vertices and the same faces */ 1281 for (e = eStart; e < eMax; ++e) { 1282 for (r = 0; r < 2; ++r) { 1283 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1284 PetscInt size; 1285 1286 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1287 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1288 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1289 } 1290 } 1291 /* Interior face edges have 2 vertices and 2 + cell faces supports */ 1292 for (f = fStart; f < fMax; ++f) { 1293 for (r = 0; r < 3; ++r) { 1294 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1295 PetscInt size; 1296 1297 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1298 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1299 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1300 } 1301 } 1302 /* Interior cell edges have 2 vertices and 3 faces */ 1303 for (c = cStart; c < cMax; ++c) { 1304 for (r = 0; r < 4; ++r) { 1305 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 1306 1307 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1308 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1309 } 1310 } 1311 /* Hybrid edges have 2 vertices and the same faces */ 1312 for (e = eMax; e < eEnd; ++e) { 1313 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 1314 PetscInt size; 1315 1316 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1317 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1318 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1319 } 1320 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1321 for (f = fMax; f < fEnd; ++f) { 1322 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 1323 PetscInt size; 1324 1325 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1326 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1327 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1328 } 1329 /* Hybrid cell edges have 2 vertices and 3 faces */ 1330 for (c = cMax; c < cEnd; ++c) { 1331 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1332 1333 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1334 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1335 } 1336 /* Old vertices have identical supports */ 1337 for (v = vStart; v < vEnd; ++v) { 1338 const PetscInt newp = vStartNew + (v - vStart); 1339 PetscInt size; 1340 1341 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1342 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1343 } 1344 /* Interior edge vertices have 2 + faces supports */ 1345 for (e = eStart; e < eMax; ++e) { 1346 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1347 PetscInt size; 1348 1349 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1350 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1351 } 1352 /* Interior face vertices have 3 + cells supports */ 1353 for (f = fStart; f < fMax; ++f) { 1354 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 1355 PetscInt size; 1356 1357 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1358 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1359 } 1360 /* Interior cell vertices have 4 supports */ 1361 for (c = cStart; c < cMax; ++c) { 1362 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 1363 1364 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1365 } 1366 break; 1367 case REFINER_HEX_3D: 1368 /* All cells have 6 faces */ 1369 for (c = cStart; c < cEnd; ++c) { 1370 for (r = 0; r < 8; ++r) { 1371 const PetscInt newp = (c - cStart)*8 + r; 1372 1373 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1374 } 1375 } 1376 /* Split faces have 4 edges and the same cells as the parent */ 1377 for (f = fStart; f < fEnd; ++f) { 1378 for (r = 0; r < 4; ++r) { 1379 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1380 PetscInt size; 1381 1382 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1383 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1384 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1385 } 1386 } 1387 /* Interior faces have 4 edges and 2 cells */ 1388 for (c = cStart; c < cEnd; ++c) { 1389 for (r = 0; r < 12; ++r) { 1390 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 1391 1392 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1393 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1394 } 1395 } 1396 /* Split edges have 2 vertices and the same faces as the parent */ 1397 for (e = eStart; e < eEnd; ++e) { 1398 for (r = 0; r < 2; ++r) { 1399 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1400 PetscInt size; 1401 1402 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1403 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1404 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1405 } 1406 } 1407 /* Face edges have 2 vertices and 2+cells faces */ 1408 for (f = fStart; f < fEnd; ++f) { 1409 for (r = 0; r < 4; ++r) { 1410 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 1411 PetscInt size; 1412 1413 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1414 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1415 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1416 } 1417 } 1418 /* Cell edges have 2 vertices and 4 faces */ 1419 for (c = cStart; c < cEnd; ++c) { 1420 for (r = 0; r < 6; ++r) { 1421 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 1422 1423 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1424 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1425 } 1426 } 1427 /* Old vertices have identical supports */ 1428 for (v = vStart; v < vEnd; ++v) { 1429 const PetscInt newp = vStartNew + (v - vStart); 1430 PetscInt size; 1431 1432 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1433 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1434 } 1435 /* Edge vertices have 2 + faces supports */ 1436 for (e = eStart; e < eEnd; ++e) { 1437 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1438 PetscInt size; 1439 1440 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1441 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1442 } 1443 /* Face vertices have 4 + cells supports */ 1444 for (f = fStart; f < fEnd; ++f) { 1445 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 1446 PetscInt size; 1447 1448 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1449 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1450 } 1451 /* Cell vertices have 6 supports */ 1452 for (c = cStart; c < cEnd; ++c) { 1453 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 1454 1455 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1456 } 1457 break; 1458 case REFINER_HYBRID_HEX_3D: 1459 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 1460 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1461 /* Interior cells have 6 faces */ 1462 for (c = cStart; c < cMax; ++c) { 1463 for (r = 0; r < 8; ++r) { 1464 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1465 1466 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1467 } 1468 } 1469 /* Hybrid cells have 6 faces */ 1470 for (c = cMax; c < cEnd; ++c) { 1471 for (r = 0; r < 4; ++r) { 1472 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1473 1474 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1475 } 1476 } 1477 /* Interior split faces have 4 edges and the same cells as the parent */ 1478 for (f = fStart; f < fMax; ++f) { 1479 for (r = 0; r < 4; ++r) { 1480 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1481 PetscInt size; 1482 1483 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1484 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1485 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1486 } 1487 } 1488 /* Interior cell faces have 4 edges and 2 cells */ 1489 for (c = cStart; c < cMax; ++c) { 1490 for (r = 0; r < 12; ++r) { 1491 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1492 1493 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1494 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1495 } 1496 } 1497 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1498 for (f = fMax; f < fEnd; ++f) { 1499 for (r = 0; r < 2; ++r) { 1500 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1501 PetscInt size; 1502 1503 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1504 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1505 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1506 } 1507 } 1508 /* Hybrid cells faces have 4 edges and 2 cells */ 1509 for (c = cMax; c < cEnd; ++c) { 1510 for (r = 0; r < 4; ++r) { 1511 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1512 1513 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1514 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1515 } 1516 } 1517 /* Interior split edges have 2 vertices and the same faces as the parent */ 1518 for (e = eStart; e < eMax; ++e) { 1519 for (r = 0; r < 2; ++r) { 1520 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1521 PetscInt size; 1522 1523 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1524 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1525 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1526 } 1527 } 1528 /* Interior face edges have 2 vertices and 2+cells faces */ 1529 for (f = fStart; f < fMax; ++f) { 1530 for (r = 0; r < 4; ++r) { 1531 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1532 PetscInt size; 1533 1534 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1535 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1536 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1537 } 1538 } 1539 /* Interior cell edges have 2 vertices and 4 faces */ 1540 for (c = cStart; c < cMax; ++c) { 1541 for (r = 0; r < 6; ++r) { 1542 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1543 1544 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1545 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1546 } 1547 } 1548 /* Hybrid edges have 2 vertices and the same faces */ 1549 for (e = eMax; e < eEnd; ++e) { 1550 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1551 PetscInt size; 1552 1553 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1554 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1555 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1556 } 1557 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1558 for (f = fMax; f < fEnd; ++f) { 1559 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1560 PetscInt size; 1561 1562 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1563 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1564 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1565 } 1566 /* Hybrid cell edges have 2 vertices and 4 faces */ 1567 for (c = cMax; c < cEnd; ++c) { 1568 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1569 1570 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1571 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1572 } 1573 /* Interior vertices have identical supports */ 1574 for (v = vStart; v < vEnd; ++v) { 1575 const PetscInt newp = vStartNew + (v - vStart); 1576 PetscInt size; 1577 1578 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1579 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1580 } 1581 /* Interior edge vertices have 2 + faces supports */ 1582 for (e = eStart; e < eMax; ++e) { 1583 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1584 PetscInt size; 1585 1586 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1587 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1588 } 1589 /* Interior face vertices have 4 + cells supports */ 1590 for (f = fStart; f < fMax; ++f) { 1591 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1592 PetscInt size; 1593 1594 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1595 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1596 } 1597 /* Interior cell vertices have 6 supports */ 1598 for (c = cStart; c < cMax; ++c) { 1599 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1600 1601 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1602 } 1603 break; 1604 default: 1605 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 1606 } 1607 PetscFunctionReturn(0); 1608 } 1609 1610 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1611 { 1612 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1613 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1614 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1615 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r, p; 1616 PetscErrorCode ierr; 1617 1618 PetscFunctionBegin; 1619 if (!refiner) PetscFunctionReturn(0); 1620 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1621 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1622 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1623 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1624 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1625 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1626 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1627 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1628 switch (refiner) { 1629 case REFINER_SIMPLEX_1D: 1630 /* Max support size of refined mesh is 2 */ 1631 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1632 /* All cells have 2 vertices */ 1633 for (c = cStart; c < cEnd; ++c) { 1634 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1635 1636 for (r = 0; r < 2; ++r) { 1637 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1638 const PetscInt *cone; 1639 PetscInt coneNew[2]; 1640 1641 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1642 coneNew[0] = vStartNew + (cone[0] - vStart); 1643 coneNew[1] = vStartNew + (cone[1] - vStart); 1644 coneNew[(r+1)%2] = newv; 1645 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1646 #if 1 1647 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp, cStartNew, cEndNew); 1648 for (p = 0; p < 2; ++p) { 1649 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1650 } 1651 #endif 1652 } 1653 } 1654 /* Old vertices have identical supports */ 1655 for (v = vStart; v < vEnd; ++v) { 1656 const PetscInt newp = vStartNew + (v - vStart); 1657 const PetscInt *support, *cone; 1658 PetscInt size, s; 1659 1660 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1661 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1662 for (s = 0; s < size; ++s) { 1663 PetscInt r = 0; 1664 1665 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1666 if (cone[1] == v) r = 1; 1667 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1668 } 1669 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1670 #if 1 1671 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1672 for (p = 0; p < size; ++p) { 1673 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 1674 } 1675 #endif 1676 } 1677 /* Cell vertices have support of 2 cells */ 1678 for (c = cStart; c < cEnd; ++c) { 1679 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1680 1681 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1682 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1683 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1684 #if 1 1685 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1686 for (p = 0; p < 2; ++p) { 1687 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 1688 } 1689 #endif 1690 } 1691 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1692 break; 1693 case REFINER_SIMPLEX_2D: 1694 /* 1695 2 1696 |\ 1697 | \ 1698 | \ 1699 | \ 1700 | C \ 1701 | \ 1702 | \ 1703 2---1---1 1704 |\ D / \ 1705 | 2 0 \ 1706 |A \ / B \ 1707 0---0-------1 1708 */ 1709 /* All cells have 3 faces */ 1710 for (c = cStart; c < cEnd; ++c) { 1711 const PetscInt newp = cStartNew + (c - cStart)*4; 1712 const PetscInt *cone, *ornt; 1713 PetscInt coneNew[3], orntNew[3]; 1714 1715 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1716 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1717 /* A triangle */ 1718 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1719 orntNew[0] = ornt[0]; 1720 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1721 orntNew[1] = -2; 1722 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1723 orntNew[2] = ornt[2]; 1724 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1725 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1726 #if 1 1727 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 1728 for (p = 0; p < 3; ++p) { 1729 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1730 } 1731 #endif 1732 /* B triangle */ 1733 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1734 orntNew[0] = ornt[0]; 1735 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1736 orntNew[1] = ornt[1]; 1737 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1738 orntNew[2] = -2; 1739 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1740 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1741 #if 1 1742 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 1743 for (p = 0; p < 3; ++p) { 1744 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1745 } 1746 #endif 1747 /* C triangle */ 1748 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1749 orntNew[0] = -2; 1750 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1751 orntNew[1] = ornt[1]; 1752 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1753 orntNew[2] = ornt[2]; 1754 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1755 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1756 #if 1 1757 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 1758 for (p = 0; p < 3; ++p) { 1759 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1760 } 1761 #endif 1762 /* D triangle */ 1763 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1764 orntNew[0] = 0; 1765 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1766 orntNew[1] = 0; 1767 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1768 orntNew[2] = 0; 1769 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1770 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1771 #if 1 1772 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 1773 for (p = 0; p < 3; ++p) { 1774 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1775 } 1776 #endif 1777 } 1778 /* Split faces have 2 vertices and the same cells as the parent */ 1779 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1780 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1781 for (f = fStart; f < fEnd; ++f) { 1782 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1783 1784 for (r = 0; r < 2; ++r) { 1785 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1786 const PetscInt *cone, *ornt, *support; 1787 PetscInt coneNew[2], coneSize, c, supportSize, s; 1788 1789 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1790 coneNew[0] = vStartNew + (cone[0] - vStart); 1791 coneNew[1] = vStartNew + (cone[1] - vStart); 1792 coneNew[(r+1)%2] = newv; 1793 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1794 #if 1 1795 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1796 for (p = 0; p < 2; ++p) { 1797 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1798 } 1799 #endif 1800 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1801 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1802 for (s = 0; s < supportSize; ++s) { 1803 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1804 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1805 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1806 for (c = 0; c < coneSize; ++c) { 1807 if (cone[c] == f) break; 1808 } 1809 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1810 } 1811 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1812 #if 1 1813 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1814 for (p = 0; p < supportSize; ++p) { 1815 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 1816 } 1817 #endif 1818 } 1819 } 1820 /* Interior faces have 2 vertices and 2 cells */ 1821 for (c = cStart; c < cEnd; ++c) { 1822 const PetscInt *cone; 1823 1824 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1825 for (r = 0; r < 3; ++r) { 1826 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1827 PetscInt coneNew[2]; 1828 PetscInt supportNew[2]; 1829 1830 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1831 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1832 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1833 #if 1 1834 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1835 for (p = 0; p < 2; ++p) { 1836 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 1837 } 1838 #endif 1839 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1840 supportNew[1] = (c - cStart)*4 + 3; 1841 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1842 #if 1 1843 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1844 for (p = 0; p < 2; ++p) { 1845 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 1846 } 1847 #endif 1848 } 1849 } 1850 /* Old vertices have identical supports */ 1851 for (v = vStart; v < vEnd; ++v) { 1852 const PetscInt newp = vStartNew + (v - vStart); 1853 const PetscInt *support, *cone; 1854 PetscInt size, s; 1855 1856 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1857 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1858 for (s = 0; s < size; ++s) { 1859 PetscInt r = 0; 1860 1861 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1862 if (cone[1] == v) r = 1; 1863 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1864 } 1865 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1866 #if 1 1867 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1868 for (p = 0; p < size; ++p) { 1869 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 1870 } 1871 #endif 1872 } 1873 /* Face vertices have 2 + cells*2 supports */ 1874 for (f = fStart; f < fEnd; ++f) { 1875 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 1876 const PetscInt *cone, *support; 1877 PetscInt size, s; 1878 1879 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1880 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1881 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 1882 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 1883 for (s = 0; s < size; ++s) { 1884 PetscInt r = 0; 1885 1886 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1887 if (cone[1] == f) r = 1; 1888 else if (cone[2] == f) r = 2; 1889 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 1890 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 1891 } 1892 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1893 #if 1 1894 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 1895 for (p = 0; p < 2+size*2; ++p) { 1896 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 1897 } 1898 #endif 1899 } 1900 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1901 break; 1902 case REFINER_SIMPLEX_TO_HEX_2D: 1903 /* 1904 2 1905 |\ 1906 | \ 1907 | \ 1908 | \ 1909 | C \ 1910 | \ 1911 2 1 1912 |\ / \ 1913 | 2 1 \ 1914 | \/ \ 1915 | | \ 1916 |A | B \ 1917 | 0 \ 1918 | | \ 1919 0---0----------1 1920 */ 1921 /* All cells have 4 faces */ 1922 for (c = cStart; c < cEnd; ++c) { 1923 const PetscInt newp = cStartNew + (c - cStart)*3; 1924 const PetscInt *cone, *ornt; 1925 PetscInt coneNew[4], orntNew[4]; 1926 1927 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1928 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1929 /* A quad */ 1930 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1931 orntNew[0] = ornt[0]; 1932 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1933 orntNew[1] = 0; 1934 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1935 orntNew[2] = -2; 1936 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1937 orntNew[3] = ornt[2]; 1938 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1939 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1940 #if 1 1941 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 1942 for (p = 0; p < 4; ++p) { 1943 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1944 } 1945 #endif 1946 /* B quad */ 1947 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1948 orntNew[0] = ornt[0]; 1949 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1950 orntNew[1] = ornt[1]; 1951 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1952 orntNew[2] = 0; 1953 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1954 orntNew[3] = -2; 1955 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1956 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1957 #if 1 1958 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 1959 for (p = 0; p < 4; ++p) { 1960 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1961 } 1962 #endif 1963 /* C quad */ 1964 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1965 orntNew[0] = ornt[1]; 1966 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1967 orntNew[1] = ornt[2]; 1968 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1969 orntNew[2] = 0; 1970 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1971 orntNew[3] = -2; 1972 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1973 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1974 #if 1 1975 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 1976 for (p = 0; p < 4; ++p) { 1977 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 1978 } 1979 #endif 1980 } 1981 /* Split faces have 2 vertices and the same cells as the parent */ 1982 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1983 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1984 for (f = fStart; f < fEnd; ++f) { 1985 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1986 1987 for (r = 0; r < 2; ++r) { 1988 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1989 const PetscInt *cone, *ornt, *support; 1990 PetscInt coneNew[2], coneSize, c, supportSize, s; 1991 1992 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1993 coneNew[0] = vStartNew + (cone[0] - vStart); 1994 coneNew[1] = vStartNew + (cone[1] - vStart); 1995 coneNew[(r+1)%2] = newv; 1996 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1997 #if 1 1998 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 1999 for (p = 0; p < 2; ++p) { 2000 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2001 } 2002 #endif 2003 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2004 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2005 for (s = 0; s < supportSize; ++s) { 2006 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2007 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2008 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2009 for (c = 0; c < coneSize; ++c) { 2010 if (cone[c] == f) break; 2011 } 2012 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2013 } 2014 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2015 #if 1 2016 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2017 for (p = 0; p < supportSize; ++p) { 2018 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 2019 } 2020 #endif 2021 } 2022 } 2023 /* Interior faces have 2 vertices and 2 cells */ 2024 for (c = cStart; c < cEnd; ++c) { 2025 const PetscInt *cone; 2026 2027 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2028 for (r = 0; r < 3; ++r) { 2029 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2030 PetscInt coneNew[2]; 2031 PetscInt supportNew[2]; 2032 2033 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2034 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2035 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2036 #if 1 2037 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2038 for (p = 0; p < 2; ++p) { 2039 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2040 } 2041 #endif 2042 supportNew[0] = (c - cStart)*3 + r%3; 2043 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2044 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2045 #if 1 2046 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2047 for (p = 0; p < 2; ++p) { 2048 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 2049 } 2050 #endif 2051 } 2052 } 2053 /* Old vertices have identical supports */ 2054 for (v = vStart; v < vEnd; ++v) { 2055 const PetscInt newp = vStartNew + (v - vStart); 2056 const PetscInt *support, *cone; 2057 PetscInt size, s; 2058 2059 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2060 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2061 for (s = 0; s < size; ++s) { 2062 PetscInt r = 0; 2063 2064 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2065 if (cone[1] == v) r = 1; 2066 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2067 } 2068 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2069 #if 1 2070 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2071 for (p = 0; p < size; ++p) { 2072 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2073 } 2074 #endif 2075 } 2076 /* Split-face vertices have cells + 2 supports */ 2077 for (f = fStart; f < fEnd; ++f) { 2078 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2079 const PetscInt *cone, *support; 2080 PetscInt size, s; 2081 2082 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2083 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2084 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2085 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2086 for (s = 0; s < size; ++s) { 2087 PetscInt r = 0; 2088 2089 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2090 if (cone[1] == f) r = 1; 2091 else if (cone[2] == f) r = 2; 2092 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2093 } 2094 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2095 #if 1 2096 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2097 for (p = 0; p < 2+size; ++p) { 2098 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2099 } 2100 #endif 2101 } 2102 /* Interior vertices have 3 supports */ 2103 for (c = cStart; c < cEnd; ++c) { 2104 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2105 2106 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2107 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2108 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2109 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2110 } 2111 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2112 break; 2113 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 2114 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2115 cMax = PetscMin(cEnd, cMax); 2116 for (c = cStart; c < cMax; ++c) { 2117 const PetscInt newp = cStartNew + (c - cStart)*3; 2118 const PetscInt *cone, *ornt; 2119 PetscInt coneNew[4], orntNew[4]; 2120 2121 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2122 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2123 /* A quad */ 2124 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2125 orntNew[0] = ornt[0]; 2126 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2127 orntNew[1] = 0; 2128 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2129 orntNew[2] = -2; 2130 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2131 orntNew[3] = ornt[2]; 2132 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2133 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2134 #if 1 2135 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 2136 for (p = 0; p < 4; ++p) { 2137 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2138 } 2139 #endif 2140 /* B quad */ 2141 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2142 orntNew[0] = ornt[0]; 2143 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2144 orntNew[1] = ornt[1]; 2145 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2146 orntNew[2] = 0; 2147 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2148 orntNew[3] = -2; 2149 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2150 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2151 #if 1 2152 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 2153 for (p = 0; p < 4; ++p) { 2154 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2155 } 2156 #endif 2157 /* C quad */ 2158 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2159 orntNew[0] = ornt[1]; 2160 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2161 orntNew[1] = ornt[2]; 2162 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2163 orntNew[2] = 0; 2164 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2165 orntNew[3] = -2; 2166 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2167 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2168 #if 1 2169 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 2170 for (p = 0; p < 4; ++p) { 2171 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2172 } 2173 #endif 2174 } 2175 /* 2176 2---------1---------3 2177 | | | 2178 | D 1 C | 2179 | | | 2180 2----2----0----3----3 2181 | | | 2182 | A 0 B | 2183 | | | 2184 0---------0---------1 2185 */ 2186 /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */ 2187 for (c = cMax; c < cEnd; ++c) { 2188 const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4; 2189 const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4; 2190 const PetscInt *cone, *ornt; 2191 PetscInt coneNew[4], orntNew[4]; 2192 2193 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2194 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2195 /* A quad */ 2196 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2197 orntNew[0] = ornt[0]; 2198 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2199 orntNew[1] = 0; 2200 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2201 orntNew[2] = -2; 2202 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2203 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2204 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2205 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2206 #if 1 2207 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 2208 for (p = 0; p < 4; ++p) { 2209 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2210 } 2211 #endif 2212 /* B quad */ 2213 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2214 orntNew[0] = ornt[0]; 2215 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2216 orntNew[1] = ornt[3]; 2217 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2218 orntNew[2] = 0; 2219 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2220 orntNew[3] = -2; 2221 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2222 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2223 #if 1 2224 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 2225 for (p = 0; p < 4; ++p) { 2226 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2227 } 2228 #endif 2229 /* C quad */ 2230 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2231 orntNew[0] = -2; 2232 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2233 orntNew[1] = ornt[3]; 2234 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2235 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2236 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2237 orntNew[3] = 0; 2238 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2239 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2240 #if 1 2241 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 2242 for (p = 0; p < 4; ++p) { 2243 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2244 } 2245 #endif 2246 /* D quad */ 2247 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2248 orntNew[0] = 0; 2249 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2250 orntNew[1] = -2; 2251 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2252 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2253 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2254 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2255 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2256 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2257 #if 1 2258 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 2259 for (p = 0; p < 4; ++p) { 2260 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2261 } 2262 #endif 2263 } 2264 /* Split faces have 2 vertices and the same cells as the parent */ 2265 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2266 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2267 for (f = fStart; f < fEnd; ++f) { 2268 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2269 2270 for (r = 0; r < 2; ++r) { 2271 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2272 const PetscInt *cone, *ornt, *support; 2273 PetscInt coneNew[2], coneSize, c, supportSize, s; 2274 2275 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2276 coneNew[0] = vStartNew + (cone[0] - vStart); 2277 coneNew[1] = vStartNew + (cone[1] - vStart); 2278 coneNew[(r+1)%2] = newv; 2279 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2280 #if 1 2281 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2282 for (p = 0; p < 2; ++p) { 2283 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2284 } 2285 #endif 2286 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2287 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2288 for (s = 0; s < supportSize; ++s) { 2289 const PetscInt p2q[4][2] = { {0, 1}, 2290 {3, 2}, 2291 {0, 3}, 2292 {1, 2} }; 2293 2294 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2295 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2296 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2297 for (c = 0; c < coneSize; ++c) { 2298 if (cone[c] == f) break; 2299 } 2300 if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2301 else if (coneSize == 4) supportRef[s] = cStartNew + (cMax - cStart)*3 + (support[s] - cMax)*4 + (ornt[c] < 0 ? p2q[c][(r+1)%2] : p2q[c][r]); 2302 else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2303 } 2304 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2305 #if 1 2306 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2307 for (p = 0; p < supportSize; ++p) { 2308 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 2309 } 2310 #endif 2311 } 2312 } 2313 /* Interior faces have 2 vertices and 2 cells */ 2314 for (c = cStart; c < cMax; ++c) { 2315 const PetscInt *cone; 2316 2317 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2318 for (r = 0; r < 3; ++r) { 2319 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2320 PetscInt coneNew[2]; 2321 PetscInt supportNew[2]; 2322 2323 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2324 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2325 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2326 #if 1 2327 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2328 for (p = 0; p < 2; ++p) { 2329 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2330 } 2331 #endif 2332 supportNew[0] = (c - cStart)*3 + r%3; 2333 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2334 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2335 #if 1 2336 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2337 for (p = 0; p < 2; ++p) { 2338 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 2339 } 2340 #endif 2341 } 2342 } 2343 /* Hybrid interior faces have 2 vertices and 2 cells */ 2344 for (c = cMax; c < cEnd; ++c) { 2345 const PetscInt *cone; 2346 PetscInt coneNew[2], supportNew[2]; 2347 2348 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2349 for (r = 0; r < 4; ++r) { 2350 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 2351 2352 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2353 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax); 2354 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2355 #if 1 2356 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2357 for (p = 0; p < 2; ++p) { 2358 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2359 } 2360 #endif 2361 if (r==0) { 2362 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2363 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2364 } else if (r==1) { 2365 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2366 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2367 } else if (r==2) { 2368 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2369 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2370 } else { 2371 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2372 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2373 } 2374 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2375 #if 1 2376 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2377 for (p = 0; p < 2; ++p) { 2378 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 2379 } 2380 #endif 2381 } 2382 } 2383 /* Old vertices have identical supports */ 2384 for (v = vStart; v < vEnd; ++v) { 2385 const PetscInt newp = vStartNew + (v - vStart); 2386 const PetscInt *support, *cone; 2387 PetscInt size, s; 2388 2389 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2390 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2391 for (s = 0; s < size; ++s) { 2392 PetscInt r = 0; 2393 2394 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2395 if (cone[1] == v) r = 1; 2396 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2397 } 2398 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2399 #if 1 2400 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2401 for (p = 0; p < size; ++p) { 2402 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2403 } 2404 #endif 2405 } 2406 /* Split-face vertices have cells + 2 supports */ 2407 for (f = fStart; f < fEnd; ++f) { 2408 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2409 const PetscInt *cone, *support; 2410 PetscInt size, s; 2411 2412 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2413 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2414 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2415 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2416 for (s = 0; s < size; ++s) { 2417 PetscInt r = 0, coneSize; 2418 2419 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2420 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2421 if (coneSize == 3) { 2422 if (cone[1] == f) r = 1; 2423 else if (cone[2] == f) r = 2; 2424 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2425 } else if (coneSize == 4) { 2426 if (cone[1] == f) r = 1; 2427 else if (cone[2] == f) r = 2; 2428 else if (cone[3] == f) r = 3; 2429 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r; 2430 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2431 } 2432 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2433 #if 1 2434 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2435 for (p = 0; p < 2+size; ++p) { 2436 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2437 } 2438 #endif 2439 } 2440 /* Interior vertices have 3 supports */ 2441 for (c = cStart; c < cMax; ++c) { 2442 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2443 2444 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2445 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2446 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2447 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2448 } 2449 /* Hybrid interior vertices have 4 supports */ 2450 for (c = cMax; c < cEnd; ++c) { 2451 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2452 2453 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0; 2454 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1; 2455 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2; 2456 supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3; 2457 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2458 } 2459 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2460 break; 2461 case REFINER_HEX_2D: 2462 /* 2463 3---------2---------2 2464 | | | 2465 | D 2 C | 2466 | | | 2467 3----3----0----1----1 2468 | | | 2469 | A 0 B | 2470 | | | 2471 0---------0---------1 2472 */ 2473 /* All cells have 4 faces */ 2474 for (c = cStart; c < cEnd; ++c) { 2475 const PetscInt newp = (c - cStart)*4; 2476 const PetscInt *cone, *ornt; 2477 PetscInt coneNew[4], orntNew[4]; 2478 2479 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2480 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2481 /* A quad */ 2482 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2483 orntNew[0] = ornt[0]; 2484 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2485 orntNew[1] = 0; 2486 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2487 orntNew[2] = -2; 2488 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2489 orntNew[3] = ornt[3]; 2490 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2491 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2492 #if 1 2493 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 2494 for (p = 0; p < 4; ++p) { 2495 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2496 } 2497 #endif 2498 /* B quad */ 2499 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2500 orntNew[0] = ornt[0]; 2501 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2502 orntNew[1] = ornt[1]; 2503 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2504 orntNew[2] = -2; 2505 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2506 orntNew[3] = -2; 2507 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2508 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2509 #if 1 2510 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 2511 for (p = 0; p < 4; ++p) { 2512 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2513 } 2514 #endif 2515 /* C quad */ 2516 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2517 orntNew[0] = 0; 2518 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2519 orntNew[1] = ornt[1]; 2520 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2521 orntNew[2] = ornt[2]; 2522 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2523 orntNew[3] = -2; 2524 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2525 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2526 #if 1 2527 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 2528 for (p = 0; p < 4; ++p) { 2529 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2530 } 2531 #endif 2532 /* D quad */ 2533 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2534 orntNew[0] = 0; 2535 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2536 orntNew[1] = 0; 2537 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2538 orntNew[2] = ornt[2]; 2539 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2540 orntNew[3] = ornt[3]; 2541 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2542 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2543 #if 1 2544 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 2545 for (p = 0; p < 4; ++p) { 2546 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2547 } 2548 #endif 2549 } 2550 /* Split faces have 2 vertices and the same cells as the parent */ 2551 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2552 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2553 for (f = fStart; f < fEnd; ++f) { 2554 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2555 2556 for (r = 0; r < 2; ++r) { 2557 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2558 const PetscInt *cone, *ornt, *support; 2559 PetscInt coneNew[2], coneSize, c, supportSize, s; 2560 2561 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2562 coneNew[0] = vStartNew + (cone[0] - vStart); 2563 coneNew[1] = vStartNew + (cone[1] - vStart); 2564 coneNew[(r+1)%2] = newv; 2565 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2566 #if 1 2567 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2568 for (p = 0; p < 2; ++p) { 2569 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2570 } 2571 #endif 2572 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2573 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2574 for (s = 0; s < supportSize; ++s) { 2575 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2576 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2577 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2578 for (c = 0; c < coneSize; ++c) { 2579 if (cone[c] == f) break; 2580 } 2581 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2582 } 2583 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2584 #if 1 2585 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2586 for (p = 0; p < supportSize; ++p) { 2587 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 2588 } 2589 #endif 2590 } 2591 } 2592 /* Interior faces have 2 vertices and 2 cells */ 2593 for (c = cStart; c < cEnd; ++c) { 2594 const PetscInt *cone; 2595 PetscInt coneNew[2], supportNew[2]; 2596 2597 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2598 for (r = 0; r < 4; ++r) { 2599 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2600 2601 if (r==1 || r==2) { 2602 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2603 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2604 } else { 2605 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2606 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2607 } 2608 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2609 #if 1 2610 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2611 for (p = 0; p < 2; ++p) { 2612 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2613 } 2614 #endif 2615 supportNew[0] = (c - cStart)*4 + r; 2616 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2617 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2618 #if 1 2619 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2620 for (p = 0; p < 2; ++p) { 2621 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 2622 } 2623 #endif 2624 } 2625 } 2626 /* Old vertices have identical supports */ 2627 for (v = vStart; v < vEnd; ++v) { 2628 const PetscInt newp = vStartNew + (v - vStart); 2629 const PetscInt *support, *cone; 2630 PetscInt size, s; 2631 2632 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2633 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2634 for (s = 0; s < size; ++s) { 2635 PetscInt r = 0; 2636 2637 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2638 if (cone[1] == v) r = 1; 2639 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2640 } 2641 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2642 #if 1 2643 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2644 for (p = 0; p < size; ++p) { 2645 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2646 } 2647 #endif 2648 } 2649 /* Face vertices have 2 + cells supports */ 2650 for (f = fStart; f < fEnd; ++f) { 2651 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2652 const PetscInt *cone, *support; 2653 PetscInt size, s; 2654 2655 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2656 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2657 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2658 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2659 for (s = 0; s < size; ++s) { 2660 PetscInt r = 0; 2661 2662 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2663 if (cone[1] == f) r = 1; 2664 else if (cone[2] == f) r = 2; 2665 else if (cone[3] == f) r = 3; 2666 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 2667 } 2668 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2669 #if 1 2670 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2671 for (p = 0; p < 2+size; ++p) { 2672 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2673 } 2674 #endif 2675 } 2676 /* Cell vertices have 4 supports */ 2677 for (c = cStart; c < cEnd; ++c) { 2678 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2679 PetscInt supportNew[4]; 2680 2681 for (r = 0; r < 4; ++r) { 2682 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2683 } 2684 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2685 } 2686 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2687 break; 2688 case REFINER_HYBRID_SIMPLEX_2D: 2689 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2690 cMax = PetscMin(cEnd, cMax); 2691 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2692 fMax = PetscMin(fEnd, fMax); 2693 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2694 /* Interior cells have 3 faces */ 2695 for (c = cStart; c < cMax; ++c) { 2696 const PetscInt newp = cStartNew + (c - cStart)*4; 2697 const PetscInt *cone, *ornt; 2698 PetscInt coneNew[3], orntNew[3]; 2699 2700 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2701 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2702 /* A triangle */ 2703 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2704 orntNew[0] = ornt[0]; 2705 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2706 orntNew[1] = -2; 2707 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2708 orntNew[2] = ornt[2]; 2709 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2710 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2711 #if 1 2712 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew); 2713 for (p = 0; p < 3; ++p) { 2714 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2715 } 2716 #endif 2717 /* B triangle */ 2718 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2719 orntNew[0] = ornt[0]; 2720 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2721 orntNew[1] = ornt[1]; 2722 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2723 orntNew[2] = -2; 2724 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2725 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2726 #if 1 2727 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew); 2728 for (p = 0; p < 3; ++p) { 2729 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2730 } 2731 #endif 2732 /* C triangle */ 2733 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2734 orntNew[0] = -2; 2735 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2736 orntNew[1] = ornt[1]; 2737 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2738 orntNew[2] = ornt[2]; 2739 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2740 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2741 #if 1 2742 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew); 2743 for (p = 0; p < 3; ++p) { 2744 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2745 } 2746 #endif 2747 /* D triangle */ 2748 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2749 orntNew[0] = 0; 2750 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2751 orntNew[1] = 0; 2752 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2753 orntNew[2] = 0; 2754 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2755 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2756 #if 1 2757 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew); 2758 for (p = 0; p < 3; ++p) { 2759 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 2760 } 2761 #endif 2762 } 2763 /* 2764 2----3----3 2765 | | 2766 | B | 2767 | | 2768 0----4--- 1 2769 | | 2770 | A | 2771 | | 2772 0----2----1 2773 */ 2774 /* Hybrid cells have 4 faces */ 2775 for (c = cMax; c < cEnd; ++c) { 2776 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2777 const PetscInt *cone, *ornt; 2778 PetscInt coneNew[4], orntNew[4], r; 2779 2780 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2781 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2782 r = (ornt[0] < 0 ? 1 : 0); 2783 /* A quad */ 2784 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2785 orntNew[0] = ornt[0]; 2786 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2787 orntNew[1] = ornt[1]; 2788 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2789 orntNew[2+r] = 0; 2790 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2791 orntNew[3-r] = 0; 2792 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2793 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2794 #if 1 2795 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 2796 for (p = 0; p < 4; ++p) { 2797 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2798 } 2799 #endif 2800 /* B quad */ 2801 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2802 orntNew[0] = ornt[0]; 2803 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2804 orntNew[1] = ornt[1]; 2805 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2806 orntNew[2+r] = 0; 2807 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2808 orntNew[3-r] = 0; 2809 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2810 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2811 #if 1 2812 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 2813 for (p = 0; p < 4; ++p) { 2814 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 2815 } 2816 #endif 2817 } 2818 /* Interior split faces have 2 vertices and the same cells as the parent */ 2819 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2820 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2821 for (f = fStart; f < fMax; ++f) { 2822 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2823 2824 for (r = 0; r < 2; ++r) { 2825 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2826 const PetscInt *cone, *ornt, *support; 2827 PetscInt coneNew[2], coneSize, c, supportSize, s; 2828 2829 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2830 coneNew[0] = vStartNew + (cone[0] - vStart); 2831 coneNew[1] = vStartNew + (cone[1] - vStart); 2832 coneNew[(r+1)%2] = newv; 2833 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2834 #if 1 2835 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2836 for (p = 0; p < 2; ++p) { 2837 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2838 } 2839 #endif 2840 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2841 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2842 for (s = 0; s < supportSize; ++s) { 2843 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2844 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2845 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2846 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2847 if (support[s] >= cMax) { 2848 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2849 } else { 2850 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2851 } 2852 } 2853 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2854 #if 1 2855 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2856 for (p = 0; p < supportSize; ++p) { 2857 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 2858 } 2859 #endif 2860 } 2861 } 2862 /* Interior cell faces have 2 vertices and 2 cells */ 2863 for (c = cStart; c < cMax; ++c) { 2864 const PetscInt *cone; 2865 2866 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2867 for (r = 0; r < 3; ++r) { 2868 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 2869 PetscInt coneNew[2]; 2870 PetscInt supportNew[2]; 2871 2872 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2873 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 2874 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2875 #if 1 2876 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2877 for (p = 0; p < 2; ++p) { 2878 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2879 } 2880 #endif 2881 supportNew[0] = (c - cStart)*4 + (r+1)%3; 2882 supportNew[1] = (c - cStart)*4 + 3; 2883 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2884 #if 1 2885 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2886 for (p = 0; p < 2; ++p) { 2887 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 2888 } 2889 #endif 2890 } 2891 } 2892 /* Interior hybrid faces have 2 vertices and the same cells */ 2893 for (f = fMax; f < fEnd; ++f) { 2894 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 2895 const PetscInt *cone, *ornt; 2896 const PetscInt *support; 2897 PetscInt coneNew[2]; 2898 PetscInt supportNew[2]; 2899 PetscInt size, s, r; 2900 2901 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2902 coneNew[0] = vStartNew + (cone[0] - vStart); 2903 coneNew[1] = vStartNew + (cone[1] - vStart); 2904 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2905 #if 1 2906 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2907 for (p = 0; p < 2; ++p) { 2908 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2909 } 2910 #endif 2911 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2912 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2913 for (s = 0; s < size; ++s) { 2914 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2915 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2916 for (r = 0; r < 2; ++r) { 2917 if (cone[r+2] == f) break; 2918 } 2919 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 2920 } 2921 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2922 #if 1 2923 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2924 for (p = 0; p < size; ++p) { 2925 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 2926 } 2927 #endif 2928 } 2929 /* Cell hybrid faces have 2 vertices and 2 cells */ 2930 for (c = cMax; c < cEnd; ++c) { 2931 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2932 const PetscInt *cone; 2933 PetscInt coneNew[2]; 2934 PetscInt supportNew[2]; 2935 2936 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2937 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 2938 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 2939 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2940 #if 1 2941 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2942 for (p = 0; p < 2; ++p) { 2943 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 2944 } 2945 #endif 2946 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 2947 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 2948 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2949 #if 1 2950 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 2951 for (p = 0; p < 2; ++p) { 2952 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 2953 } 2954 #endif 2955 } 2956 /* Old vertices have identical supports */ 2957 for (v = vStart; v < vEnd; ++v) { 2958 const PetscInt newp = vStartNew + (v - vStart); 2959 const PetscInt *support, *cone; 2960 PetscInt size, s; 2961 2962 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2963 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2964 for (s = 0; s < size; ++s) { 2965 if (support[s] >= fMax) { 2966 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 2967 } else { 2968 PetscInt r = 0; 2969 2970 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2971 if (cone[1] == v) r = 1; 2972 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2973 } 2974 } 2975 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2976 #if 1 2977 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 2978 for (p = 0; p < size; ++p) { 2979 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 2980 } 2981 #endif 2982 } 2983 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 2984 for (f = fStart; f < fMax; ++f) { 2985 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2986 const PetscInt *cone, *support; 2987 PetscInt size, newSize = 2, s; 2988 2989 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2990 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2991 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2992 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2993 for (s = 0; s < size; ++s) { 2994 PetscInt r = 0; 2995 2996 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2997 if (support[s] >= cMax) { 2998 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 2999 3000 newSize += 1; 3001 } else { 3002 if (cone[1] == f) r = 1; 3003 else if (cone[2] == f) r = 2; 3004 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 3005 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 3006 3007 newSize += 2; 3008 } 3009 } 3010 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3011 #if 1 3012 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3013 for (p = 0; p < newSize; ++p) { 3014 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 3015 } 3016 #endif 3017 } 3018 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3019 break; 3020 case REFINER_HYBRID_HEX_2D: 3021 /* Hybrid Hex 2D */ 3022 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 3023 cMax = PetscMin(cEnd, cMax); 3024 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 3025 fMax = PetscMin(fEnd, fMax); 3026 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 3027 /* Interior cells have 4 faces */ 3028 for (c = cStart; c < cMax; ++c) { 3029 const PetscInt newp = cStartNew + (c - cStart)*4; 3030 const PetscInt *cone, *ornt; 3031 PetscInt coneNew[4], orntNew[4]; 3032 3033 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3034 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3035 /* A quad */ 3036 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3037 orntNew[0] = ornt[0]; 3038 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3039 orntNew[1] = 0; 3040 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3041 orntNew[2] = -2; 3042 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 3043 orntNew[3] = ornt[3]; 3044 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3045 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3046 #if 1 3047 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+0, cStartNew, cMaxNew); 3048 for (p = 0; p < 4; ++p) { 3049 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 3050 } 3051 #endif 3052 /* B quad */ 3053 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3054 orntNew[0] = ornt[0]; 3055 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3056 orntNew[1] = ornt[1]; 3057 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3058 orntNew[2] = 0; 3059 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3060 orntNew[3] = -2; 3061 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3062 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3063 #if 1 3064 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+1, cStartNew, cMaxNew); 3065 for (p = 0; p < 4; ++p) { 3066 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 3067 } 3068 #endif 3069 /* C quad */ 3070 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3071 orntNew[0] = -2; 3072 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3073 orntNew[1] = ornt[1]; 3074 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 3075 orntNew[2] = ornt[2]; 3076 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3077 orntNew[3] = 0; 3078 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3079 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3080 #if 1 3081 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+2, cStartNew, cMaxNew); 3082 for (p = 0; p < 4; ++p) { 3083 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 3084 } 3085 #endif 3086 /* D quad */ 3087 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3088 orntNew[0] = 0; 3089 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3090 orntNew[1] = -2; 3091 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 3092 orntNew[2] = ornt[2]; 3093 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 3094 orntNew[3] = ornt[3]; 3095 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3096 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3097 #if 1 3098 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior cell [%d, %d)", newp+3, cStartNew, cMaxNew); 3099 for (p = 0; p < 4; ++p) { 3100 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 3101 } 3102 #endif 3103 } 3104 /* 3105 2----3----3 3106 | | 3107 | B | 3108 | | 3109 0----4--- 1 3110 | | 3111 | A | 3112 | | 3113 0----2----1 3114 */ 3115 /* Hybrid cells have 4 faces */ 3116 for (c = cMax; c < cEnd; ++c) { 3117 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 3118 const PetscInt *cone, *ornt; 3119 PetscInt coneNew[4], orntNew[4]; 3120 3121 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3122 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3123 /* A quad */ 3124 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3125 orntNew[0] = ornt[0]; 3126 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3127 orntNew[1] = ornt[1]; 3128 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 3129 orntNew[2] = 0; 3130 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3131 orntNew[3] = 0; 3132 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3133 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3134 #if 1 3135 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 3136 for (p = 0; p < 4; ++p) { 3137 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3138 } 3139 #endif 3140 /* B quad */ 3141 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3142 orntNew[0] = ornt[0]; 3143 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3144 orntNew[1] = ornt[1]; 3145 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3146 orntNew[2] = 0; 3147 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 3148 orntNew[3] = 0; 3149 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3150 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3151 #if 1 3152 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 3153 for (p = 0; p < 4; ++p) { 3154 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3155 } 3156 #endif 3157 } 3158 /* Interior split faces have 2 vertices and the same cells as the parent */ 3159 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3160 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3161 for (f = fStart; f < fMax; ++f) { 3162 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 3163 3164 for (r = 0; r < 2; ++r) { 3165 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 3166 const PetscInt *cone, *ornt, *support; 3167 PetscInt coneNew[2], coneSize, c, supportSize, s; 3168 3169 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3170 coneNew[0] = vStartNew + (cone[0] - vStart); 3171 coneNew[1] = vStartNew + (cone[1] - vStart); 3172 coneNew[(r+1)%2] = newv; 3173 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3174 #if 1 3175 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3176 for (p = 0; p < 2; ++p) { 3177 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3178 } 3179 #endif 3180 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3181 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3182 for (s = 0; s < supportSize; ++s) { 3183 if (support[s] >= cMax) { 3184 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3185 } else { 3186 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3187 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3188 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3189 for (c = 0; c < coneSize; ++c) { 3190 if (cone[c] == f) break; 3191 } 3192 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3193 } 3194 } 3195 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3196 #if 1 3197 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3198 for (p = 0; p < supportSize; ++p) { 3199 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 3200 } 3201 #endif 3202 } 3203 } 3204 /* Interior cell faces have 2 vertices and 2 cells */ 3205 for (c = cStart; c < cMax; ++c) { 3206 const PetscInt *cone; 3207 3208 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3209 for (r = 0; r < 4; ++r) { 3210 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3211 PetscInt coneNew[2], supportNew[2]; 3212 3213 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3214 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3215 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3216 #if 1 3217 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3218 for (p = 0; p < 2; ++p) { 3219 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3220 } 3221 #endif 3222 supportNew[0] = (c - cStart)*4 + r; 3223 supportNew[1] = (c - cStart)*4 + (r+1)%4; 3224 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3225 #if 1 3226 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3227 for (p = 0; p < 2; ++p) { 3228 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3229 } 3230 #endif 3231 } 3232 } 3233 /* Hybrid faces have 2 vertices and the same cells */ 3234 for (f = fMax; f < fEnd; ++f) { 3235 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 3236 const PetscInt *cone, *support; 3237 PetscInt coneNew[2], supportNew[2]; 3238 PetscInt size, s, r; 3239 3240 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3241 coneNew[0] = vStartNew + (cone[0] - vStart); 3242 coneNew[1] = vStartNew + (cone[1] - vStart); 3243 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3244 #if 1 3245 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3246 for (p = 0; p < 2; ++p) { 3247 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3248 } 3249 #endif 3250 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3251 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3252 for (s = 0; s < size; ++s) { 3253 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3254 for (r = 0; r < 2; ++r) { 3255 if (cone[r+2] == f) break; 3256 } 3257 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3258 } 3259 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3260 #if 1 3261 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3262 for (p = 0; p < size; ++p) { 3263 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3264 } 3265 #endif 3266 } 3267 /* Cell hybrid faces have 2 vertices and 2 cells */ 3268 for (c = cMax; c < cEnd; ++c) { 3269 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3270 const PetscInt *cone; 3271 PetscInt coneNew[2], supportNew[2]; 3272 3273 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3274 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3275 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3276 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3277 #if 1 3278 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3279 for (p = 0; p < 2; ++p) { 3280 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3281 } 3282 #endif 3283 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3284 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3285 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3286 #if 1 3287 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3288 for (p = 0; p < 2; ++p) { 3289 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3290 } 3291 #endif 3292 } 3293 /* Old vertices have identical supports */ 3294 for (v = vStart; v < vEnd; ++v) { 3295 const PetscInt newp = vStartNew + (v - vStart); 3296 const PetscInt *support, *cone; 3297 PetscInt size, s; 3298 3299 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3300 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3301 for (s = 0; s < size; ++s) { 3302 if (support[s] >= fMax) { 3303 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 3304 } else { 3305 PetscInt r = 0; 3306 3307 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3308 if (cone[1] == v) r = 1; 3309 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3310 } 3311 } 3312 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3313 #if 1 3314 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3315 for (p = 0; p < size; ++p) { 3316 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 3317 } 3318 #endif 3319 } 3320 /* Face vertices have 2 + cells supports */ 3321 for (f = fStart; f < fMax; ++f) { 3322 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3323 const PetscInt *cone, *support; 3324 PetscInt size, s; 3325 3326 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3327 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3328 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3329 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3330 for (s = 0; s < size; ++s) { 3331 PetscInt r = 0; 3332 3333 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3334 if (support[s] >= cMax) { 3335 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 3336 } else { 3337 if (cone[1] == f) r = 1; 3338 else if (cone[2] == f) r = 2; 3339 else if (cone[3] == f) r = 3; 3340 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 3341 } 3342 } 3343 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3344 #if 1 3345 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3346 for (p = 0; p < 2+size; ++p) { 3347 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 3348 } 3349 #endif 3350 } 3351 /* Cell vertices have 4 supports */ 3352 for (c = cStart; c < cMax; ++c) { 3353 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3354 PetscInt supportNew[4]; 3355 3356 for (r = 0; r < 4; ++r) { 3357 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3358 } 3359 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3360 } 3361 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3362 break; 3363 case REFINER_SIMPLEX_3D: 3364 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3365 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3366 for (c = cStart; c < cEnd; ++c) { 3367 const PetscInt newp = cStartNew + (c - cStart)*8; 3368 const PetscInt *cone, *ornt; 3369 PetscInt coneNew[4], orntNew[4]; 3370 3371 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3372 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3373 /* A tetrahedron: {0, a, c, d} */ 3374 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3375 orntNew[0] = ornt[0]; 3376 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3377 orntNew[1] = ornt[1]; 3378 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3379 orntNew[2] = ornt[2]; 3380 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3381 orntNew[3] = 0; 3382 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3383 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3384 #if 1 3385 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 3386 for (p = 0; p < 4; ++p) { 3387 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3388 } 3389 #endif 3390 /* B tetrahedron: {a, 1, b, e} */ 3391 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3392 orntNew[0] = ornt[0]; 3393 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3394 orntNew[1] = ornt[1]; 3395 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3396 orntNew[2] = 0; 3397 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3398 orntNew[3] = ornt[3]; 3399 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3400 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3401 #if 1 3402 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 3403 for (p = 0; p < 4; ++p) { 3404 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3405 } 3406 #endif 3407 /* C tetrahedron: {c, b, 2, f} */ 3408 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3409 orntNew[0] = ornt[0]; 3410 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3411 orntNew[1] = 0; 3412 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3413 orntNew[2] = ornt[2]; 3414 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3415 orntNew[3] = ornt[3]; 3416 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3417 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3418 #if 1 3419 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 3420 for (p = 0; p < 4; ++p) { 3421 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3422 } 3423 #endif 3424 /* D tetrahedron: {d, e, f, 3} */ 3425 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3426 orntNew[0] = 0; 3427 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3428 orntNew[1] = ornt[1]; 3429 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3430 orntNew[2] = ornt[2]; 3431 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3432 orntNew[3] = ornt[3]; 3433 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3434 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3435 #if 1 3436 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 3437 for (p = 0; p < 4; ++p) { 3438 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3439 } 3440 #endif 3441 /* A' tetrahedron: {c, d, a, f} */ 3442 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3443 orntNew[0] = -3; 3444 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3445 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3446 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3447 orntNew[2] = 0; 3448 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3449 orntNew[3] = 2; 3450 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3451 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3452 #if 1 3453 if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew); 3454 for (p = 0; p < 4; ++p) { 3455 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3456 } 3457 #endif 3458 /* B' tetrahedron: {e, b, a, f} */ 3459 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3460 orntNew[0] = -2; 3461 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 3462 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 3463 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3464 orntNew[2] = 0; 3465 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3466 orntNew[3] = 0; 3467 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3468 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3469 #if 1 3470 if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew); 3471 for (p = 0; p < 4; ++p) { 3472 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3473 } 3474 #endif 3475 /* C' tetrahedron: {f, a, c, b} */ 3476 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3477 orntNew[0] = -2; 3478 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3479 orntNew[1] = -2; 3480 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3481 orntNew[2] = -1; 3482 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 3483 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3484 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3485 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3486 #if 1 3487 if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew); 3488 for (p = 0; p < 4; ++p) { 3489 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3490 } 3491 #endif 3492 /* D' tetrahedron: {f, a, e, d} */ 3493 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3494 orntNew[0] = -2; 3495 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3496 orntNew[1] = -1; 3497 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3498 orntNew[2] = -2; 3499 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 3500 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 3501 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3502 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3503 #if 1 3504 if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew); 3505 for (p = 0; p < 4; ++p) { 3506 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 3507 } 3508 #endif 3509 } 3510 /* Split faces have 3 edges and the same cells as the parent */ 3511 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3512 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3513 for (f = fStart; f < fEnd; ++f) { 3514 const PetscInt newp = fStartNew + (f - fStart)*4; 3515 const PetscInt *cone, *ornt, *support; 3516 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3517 3518 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3519 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3520 /* A triangle */ 3521 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3522 orntNew[0] = ornt[0]; 3523 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3524 orntNew[1] = -2; 3525 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3526 orntNew[2] = ornt[2]; 3527 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3528 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3529 #if 1 3530 if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fEndNew); 3531 for (p = 0; p < 3; ++p) { 3532 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3533 } 3534 #endif 3535 /* B triangle */ 3536 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3537 orntNew[0] = ornt[0]; 3538 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3539 orntNew[1] = ornt[1]; 3540 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3541 orntNew[2] = -2; 3542 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3543 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3544 #if 1 3545 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew); 3546 for (p = 0; p < 3; ++p) { 3547 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3548 } 3549 #endif 3550 /* C triangle */ 3551 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3552 orntNew[0] = -2; 3553 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3554 orntNew[1] = ornt[1]; 3555 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3556 orntNew[2] = ornt[2]; 3557 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3558 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3559 #if 1 3560 if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fEndNew); 3561 for (p = 0; p < 3; ++p) { 3562 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3563 } 3564 #endif 3565 /* D triangle */ 3566 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3567 orntNew[0] = 0; 3568 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3569 orntNew[1] = 0; 3570 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3571 orntNew[2] = 0; 3572 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3573 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3574 #if 1 3575 if ((newp+3 < fStartNew) || (newp+3 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fEndNew); 3576 for (p = 0; p < 3; ++p) { 3577 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3578 } 3579 #endif 3580 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3581 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3582 for (r = 0; r < 4; ++r) { 3583 for (s = 0; s < supportSize; ++s) { 3584 PetscInt subf; 3585 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3586 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3587 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3588 for (c = 0; c < coneSize; ++c) { 3589 if (cone[c] == f) break; 3590 } 3591 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3592 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3593 } 3594 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3595 #if 1 3596 if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fEndNew); 3597 for (p = 0; p < supportSize; ++p) { 3598 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 3599 } 3600 #endif 3601 } 3602 } 3603 /* Interior faces have 3 edges and 2 cells */ 3604 for (c = cStart; c < cEnd; ++c) { 3605 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 3606 const PetscInt *cone, *ornt; 3607 PetscInt coneNew[3], orntNew[3]; 3608 PetscInt supportNew[2]; 3609 3610 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3611 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3612 /* Face A: {c, a, d} */ 3613 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3614 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3615 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3616 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3617 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3618 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3619 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3620 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3621 #if 1 3622 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3623 for (p = 0; p < 3; ++p) { 3624 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3625 } 3626 #endif 3627 supportNew[0] = (c - cStart)*8 + 0; 3628 supportNew[1] = (c - cStart)*8 + 0+4; 3629 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3630 #if 1 3631 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3632 for (p = 0; p < 2; ++p) { 3633 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3634 } 3635 #endif 3636 ++newp; 3637 /* Face B: {a, b, e} */ 3638 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3639 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3640 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3641 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3642 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3643 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3644 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3645 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3646 #if 1 3647 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3648 for (p = 0; p < 3; ++p) { 3649 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3650 } 3651 #endif 3652 supportNew[0] = (c - cStart)*8 + 1; 3653 supportNew[1] = (c - cStart)*8 + 1+4; 3654 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3655 #if 1 3656 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3657 for (p = 0; p < 2; ++p) { 3658 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3659 } 3660 #endif 3661 ++newp; 3662 /* Face C: {c, f, b} */ 3663 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3664 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3665 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3666 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3667 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3668 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3669 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3670 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3671 #if 1 3672 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3673 for (p = 0; p < 3; ++p) { 3674 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3675 } 3676 #endif 3677 supportNew[0] = (c - cStart)*8 + 2; 3678 supportNew[1] = (c - cStart)*8 + 2+4; 3679 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3680 #if 1 3681 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3682 for (p = 0; p < 2; ++p) { 3683 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3684 } 3685 #endif 3686 ++newp; 3687 /* Face D: {d, e, f} */ 3688 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3689 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3690 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3691 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3692 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3693 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3694 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3695 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3696 #if 1 3697 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3698 for (p = 0; p < 3; ++p) { 3699 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3700 } 3701 #endif 3702 supportNew[0] = (c - cStart)*8 + 3; 3703 supportNew[1] = (c - cStart)*8 + 3+4; 3704 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3705 #if 1 3706 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3707 for (p = 0; p < 2; ++p) { 3708 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3709 } 3710 #endif 3711 ++newp; 3712 /* Face E: {d, f, a} */ 3713 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3714 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3715 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3716 orntNew[1] = -2; 3717 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3718 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3719 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3720 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3721 #if 1 3722 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3723 for (p = 0; p < 3; ++p) { 3724 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3725 } 3726 #endif 3727 supportNew[0] = (c - cStart)*8 + 0+4; 3728 supportNew[1] = (c - cStart)*8 + 3+4; 3729 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3730 #if 1 3731 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3732 for (p = 0; p < 2; ++p) { 3733 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3734 } 3735 #endif 3736 ++newp; 3737 /* Face F: {c, a, f} */ 3738 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3739 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3740 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3741 orntNew[1] = 0; 3742 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3743 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3744 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3745 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3746 #if 1 3747 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3748 for (p = 0; p < 3; ++p) { 3749 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3750 } 3751 #endif 3752 supportNew[0] = (c - cStart)*8 + 0+4; 3753 supportNew[1] = (c - cStart)*8 + 2+4; 3754 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3755 #if 1 3756 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3757 for (p = 0; p < 2; ++p) { 3758 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3759 } 3760 #endif 3761 ++newp; 3762 /* Face G: {e, a, f} */ 3763 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3764 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3765 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3766 orntNew[1] = 0; 3767 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3768 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3769 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3770 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3771 #if 1 3772 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3773 for (p = 0; p < 3; ++p) { 3774 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3775 } 3776 #endif 3777 supportNew[0] = (c - cStart)*8 + 1+4; 3778 supportNew[1] = (c - cStart)*8 + 3+4; 3779 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3780 #if 1 3781 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3782 for (p = 0; p < 2; ++p) { 3783 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3784 } 3785 #endif 3786 ++newp; 3787 /* Face H: {a, b, f} */ 3788 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3789 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3790 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3791 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3792 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3793 orntNew[2] = -2; 3794 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3795 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3796 #if 1 3797 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3798 for (p = 0; p < 3; ++p) { 3799 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 3800 } 3801 #endif 3802 supportNew[0] = (c - cStart)*8 + 1+4; 3803 supportNew[1] = (c - cStart)*8 + 2+4; 3804 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3805 #if 1 3806 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 3807 for (p = 0; p < 2; ++p) { 3808 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 3809 } 3810 #endif 3811 ++newp; 3812 } 3813 /* Split Edges have 2 vertices and the same faces as the parent */ 3814 for (e = eStart; e < eEnd; ++e) { 3815 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3816 3817 for (r = 0; r < 2; ++r) { 3818 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3819 const PetscInt *cone, *ornt, *support; 3820 PetscInt coneNew[2], coneSize, c, supportSize, s; 3821 3822 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3823 coneNew[0] = vStartNew + (cone[0] - vStart); 3824 coneNew[1] = vStartNew + (cone[1] - vStart); 3825 coneNew[(r+1)%2] = newv; 3826 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3827 #if 1 3828 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3829 for (p = 0; p < 2; ++p) { 3830 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3831 } 3832 #endif 3833 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3834 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3835 for (s = 0; s < supportSize; ++s) { 3836 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3837 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3838 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3839 for (c = 0; c < coneSize; ++c) { 3840 if (cone[c] == e) break; 3841 } 3842 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3843 } 3844 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3845 #if 1 3846 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3847 for (p = 0; p < supportSize; ++p) { 3848 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 3849 } 3850 #endif 3851 } 3852 } 3853 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3854 for (f = fStart; f < fEnd; ++f) { 3855 const PetscInt *cone, *ornt, *support; 3856 PetscInt coneSize, supportSize, s; 3857 3858 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3859 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3860 for (r = 0; r < 3; ++r) { 3861 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3862 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3863 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3864 -1, -1, 1, 6, 0, 4, 3865 2, 5, 3, 4, -1, -1, 3866 -1, -1, 3, 6, 2, 7}; 3867 3868 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3869 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3870 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3871 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3872 #if 1 3873 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3874 for (p = 0; p < 2; ++p) { 3875 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3876 } 3877 #endif 3878 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 3879 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 3880 for (s = 0; s < supportSize; ++s) { 3881 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3882 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3883 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3884 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 3885 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 3886 er = GetTriMidEdgeInverse_Static(ornt[c], r); 3887 if (er == eint[c]) { 3888 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 3889 } else { 3890 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 3891 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 3892 } 3893 } 3894 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3895 #if 1 3896 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3897 for (p = 0; p < intFaces; ++p) { 3898 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 3899 } 3900 #endif 3901 } 3902 } 3903 /* Interior edges have 2 vertices and 4 faces */ 3904 for (c = cStart; c < cEnd; ++c) { 3905 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3906 const PetscInt *cone, *ornt, *fcone; 3907 PetscInt coneNew[2], supportNew[4], find; 3908 3909 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3910 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3911 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 3912 find = GetTriEdge_Static(ornt[0], 0); 3913 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3914 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 3915 find = GetTriEdge_Static(ornt[2], 1); 3916 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 3917 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3918 #if 1 3919 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3920 for (p = 0; p < 2; ++p) { 3921 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 3922 } 3923 #endif 3924 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3925 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3926 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3927 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3928 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3929 #if 1 3930 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 3931 for (p = 0; p < 4; ++p) { 3932 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew); 3933 } 3934 #endif 3935 } 3936 /* Old vertices have identical supports */ 3937 for (v = vStart; v < vEnd; ++v) { 3938 const PetscInt newp = vStartNew + (v - vStart); 3939 const PetscInt *support, *cone; 3940 PetscInt size, s; 3941 3942 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3943 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3944 for (s = 0; s < size; ++s) { 3945 PetscInt r = 0; 3946 3947 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3948 if (cone[1] == v) r = 1; 3949 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 3950 } 3951 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3952 #if 1 3953 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 3954 for (p = 0; p < size; ++p) { 3955 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 3956 } 3957 #endif 3958 } 3959 /* Edge vertices have 2 + face*2 + 0/1 supports */ 3960 for (e = eStart; e < eEnd; ++e) { 3961 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 3962 const PetscInt *cone, *support; 3963 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 3964 3965 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 3966 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3967 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 3968 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 3969 for (s = 0; s < size; ++s) { 3970 PetscInt r = 0; 3971 3972 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3973 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3974 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 3975 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 3976 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 3977 } 3978 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3979 for (s = 0; s < starSize*2; s += 2) { 3980 const PetscInt *cone, *ornt; 3981 PetscInt e01, e23; 3982 3983 if ((star[s] >= cStart) && (star[s] < cEnd)) { 3984 /* Check edge 0-1 */ 3985 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3986 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3987 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 3988 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 3989 /* Check edge 2-3 */ 3990 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 3991 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 3992 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 3993 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 3994 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 3995 } 3996 } 3997 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 3998 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3999 #if 1 4000 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4001 for (p = 0; p < 2+size*2+cellSize; ++p) { 4002 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 4003 } 4004 #endif 4005 } 4006 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4007 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4008 break; 4009 case REFINER_HYBRID_SIMPLEX_3D: 4010 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4011 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 4012 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4013 for (c = cStart; c < cMax; ++c) { 4014 const PetscInt newp = cStartNew + (c - cStart)*8; 4015 const PetscInt *cone, *ornt; 4016 PetscInt coneNew[4], orntNew[4]; 4017 4018 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4019 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4020 /* A tetrahedron: {0, a, c, d} */ 4021 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 4022 orntNew[0] = ornt[0]; 4023 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 4024 orntNew[1] = ornt[1]; 4025 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 4026 orntNew[2] = ornt[2]; 4027 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4028 orntNew[3] = 0; 4029 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4030 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4031 #if 1 4032 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cMaxNew); 4033 for (p = 0; p < 4; ++p) { 4034 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4035 } 4036 #endif 4037 /* B tetrahedron: {a, 1, b, e} */ 4038 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 4039 orntNew[0] = ornt[0]; 4040 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 4041 orntNew[1] = ornt[1]; 4042 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4043 orntNew[2] = 0; 4044 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 4045 orntNew[3] = ornt[3]; 4046 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4047 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4048 #if 1 4049 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cMaxNew); 4050 for (p = 0; p < 4; ++p) { 4051 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4052 } 4053 #endif 4054 /* C tetrahedron: {c, b, 2, f} */ 4055 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 4056 orntNew[0] = ornt[0]; 4057 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4058 orntNew[1] = 0; 4059 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 4060 orntNew[2] = ornt[2]; 4061 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 4062 orntNew[3] = ornt[3]; 4063 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4064 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4065 #if 1 4066 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cMaxNew); 4067 for (p = 0; p < 4; ++p) { 4068 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4069 } 4070 #endif 4071 /* D tetrahedron: {d, e, f, 3} */ 4072 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4073 orntNew[0] = 0; 4074 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 4075 orntNew[1] = ornt[1]; 4076 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 4077 orntNew[2] = ornt[2]; 4078 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 4079 orntNew[3] = ornt[3]; 4080 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4081 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4082 #if 1 4083 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew); 4084 for (p = 0; p < 4; ++p) { 4085 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4086 } 4087 #endif 4088 /* A' tetrahedron: {d, a, c, f} */ 4089 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4090 orntNew[0] = -3; 4091 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 4092 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 4093 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4094 orntNew[2] = 0; 4095 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4096 orntNew[3] = 2; 4097 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4098 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4099 #if 1 4100 if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cMaxNew); 4101 for (p = 0; p < 4; ++p) { 4102 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4103 } 4104 #endif 4105 /* B' tetrahedron: {e, b, a, f} */ 4106 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4107 orntNew[0] = -3; 4108 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4109 orntNew[1] = 1; 4110 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4111 orntNew[2] = 0; 4112 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 4113 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 4114 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4115 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4116 #if 1 4117 if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cMaxNew); 4118 for (p = 0; p < 4; ++p) { 4119 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4120 } 4121 #endif 4122 /* C' tetrahedron: {b, f, c, a} */ 4123 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4124 orntNew[0] = -3; 4125 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 4126 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 4127 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4128 orntNew[2] = -3; 4129 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4130 orntNew[3] = -2; 4131 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4132 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4133 #if 1 4134 if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cMaxNew); 4135 for (p = 0; p < 4; ++p) { 4136 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4137 } 4138 #endif 4139 /* D' tetrahedron: {f, e, d, a} */ 4140 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4141 orntNew[0] = -3; 4142 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4143 orntNew[1] = -3; 4144 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 4145 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 4146 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4147 orntNew[3] = -3; 4148 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4149 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4150 #if 1 4151 if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cMaxNew); 4152 for (p = 0; p < 4; ++p) { 4153 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4154 } 4155 #endif 4156 } 4157 /* Hybrid cells have 5 faces */ 4158 for (c = cMax; c < cEnd; ++c) { 4159 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 4160 const PetscInt *cone, *ornt, *fornt; 4161 PetscInt coneNew[5], orntNew[5], o, of, i; 4162 4163 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4164 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4165 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4166 o = ornt[0] < 0 ? -1 : 1; 4167 for (r = 0; r < 3; ++r) { 4168 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 4169 orntNew[0] = ornt[0]; 4170 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 4171 orntNew[1] = ornt[1]; 4172 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 4173 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 4174 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 4175 orntNew[i] = 0; 4176 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 4177 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 4178 orntNew[i] = 0; 4179 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 4180 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 4181 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); 4182 orntNew[i] = 0; 4183 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4184 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4185 #if 1 4186 if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+r, cMaxNew, cEndNew); 4187 for (p = 0; p < 2; ++p) { 4188 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4189 } 4190 for (p = 2; p < 5; ++p) { 4191 if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew); 4192 } 4193 #endif 4194 } 4195 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 4196 orntNew[0] = 0; 4197 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 4198 orntNew[1] = 0; 4199 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 4200 orntNew[2] = 0; 4201 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 4202 orntNew[3] = 0; 4203 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 4204 orntNew[4] = 0; 4205 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4206 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4207 #if 1 4208 if ((newp+3 < cMaxNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+3, cMaxNew, cEndNew); 4209 for (p = 0; p < 2; ++p) { 4210 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 4211 } 4212 for (p = 2; p < 5; ++p) { 4213 if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew); 4214 } 4215 #endif 4216 } 4217 /* Split faces have 3 edges and the same cells as the parent */ 4218 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4219 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4220 for (f = fStart; f < fMax; ++f) { 4221 const PetscInt newp = fStartNew + (f - fStart)*4; 4222 const PetscInt *cone, *ornt, *support; 4223 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 4224 4225 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4226 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4227 /* A triangle */ 4228 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4229 orntNew[0] = ornt[0]; 4230 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4231 orntNew[1] = -2; 4232 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4233 orntNew[2] = ornt[2]; 4234 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4235 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4236 #if 1 4237 if ((newp+0 < fStartNew) || (newp+0 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fMaxNew); 4238 for (p = 0; p < 3; ++p) { 4239 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4240 } 4241 #endif 4242 /* B triangle */ 4243 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4244 orntNew[0] = ornt[0]; 4245 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4246 orntNew[1] = ornt[1]; 4247 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4248 orntNew[2] = -2; 4249 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4250 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4251 #if 1 4252 if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew); 4253 for (p = 0; p < 3; ++p) { 4254 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4255 } 4256 #endif 4257 /* C triangle */ 4258 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4259 orntNew[0] = -2; 4260 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4261 orntNew[1] = ornt[1]; 4262 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4263 orntNew[2] = ornt[2]; 4264 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4265 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4266 #if 1 4267 if ((newp+2 < fStartNew) || (newp+2 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fMaxNew); 4268 for (p = 0; p < 3; ++p) { 4269 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4270 } 4271 #endif 4272 /* D triangle */ 4273 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4274 orntNew[0] = 0; 4275 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4276 orntNew[1] = 0; 4277 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4278 orntNew[2] = 0; 4279 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4280 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4281 #if 1 4282 if ((newp+3 < fStartNew) || (newp+3 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+3, fStartNew, fMaxNew); 4283 for (p = 0; p < 3; ++p) { 4284 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4285 } 4286 #endif 4287 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4288 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4289 for (r = 0; r < 4; ++r) { 4290 for (s = 0; s < supportSize; ++s) { 4291 PetscInt subf; 4292 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4293 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4294 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4295 for (c = 0; c < coneSize; ++c) { 4296 if (cone[c] == f) break; 4297 } 4298 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4299 if (support[s] < cMax) { 4300 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 4301 } else { 4302 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 4303 } 4304 } 4305 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4306 #if 1 4307 if ((newp+r < fStartNew) || (newp+r >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fMaxNew); 4308 for (p = 0; p < supportSize; ++p) { 4309 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior or hybrid cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 4310 } 4311 #endif 4312 } 4313 } 4314 /* Interior cell faces have 3 edges and 2 cells */ 4315 for (c = cStart; c < cMax; ++c) { 4316 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 4317 const PetscInt *cone, *ornt; 4318 PetscInt coneNew[3], orntNew[3]; 4319 PetscInt supportNew[2]; 4320 4321 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4322 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4323 /* Face A: {c, a, d} */ 4324 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4325 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4326 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4327 orntNew[1] = ornt[1] < 0 ? -2 : 0; 4328 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 4329 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4330 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4331 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4332 #if 1 4333 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4334 for (p = 0; p < 3; ++p) { 4335 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4336 } 4337 #endif 4338 supportNew[0] = (c - cStart)*8 + 0; 4339 supportNew[1] = (c - cStart)*8 + 0+4; 4340 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4341 #if 1 4342 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4343 for (p = 0; p < 2; ++p) { 4344 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 4345 } 4346 #endif 4347 ++newp; 4348 /* Face B: {a, b, e} */ 4349 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4350 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4351 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 4352 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4353 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4354 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4355 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4356 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4357 #if 1 4358 if ((newp+1 < fStartNew) || (newp+1 >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fMaxNew); 4359 for (p = 0; p < 3; ++p) { 4360 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4361 } 4362 #endif 4363 supportNew[0] = (c - cStart)*8 + 1; 4364 supportNew[1] = (c - cStart)*8 + 1+4; 4365 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4366 #if 1 4367 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4368 for (p = 0; p < 2; ++p) { 4369 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 4370 } 4371 #endif 4372 ++newp; 4373 /* Face C: {c, f, b} */ 4374 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4375 orntNew[0] = ornt[2] < 0 ? -2 : 0; 4376 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4377 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4378 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 4379 orntNew[2] = ornt[0] < 0 ? -2 : 0; 4380 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4381 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4382 #if 1 4383 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4384 for (p = 0; p < 3; ++p) { 4385 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4386 } 4387 #endif 4388 supportNew[0] = (c - cStart)*8 + 2; 4389 supportNew[1] = (c - cStart)*8 + 2+4; 4390 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4391 #if 1 4392 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4393 for (p = 0; p < 2; ++p) { 4394 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 4395 } 4396 #endif 4397 ++newp; 4398 /* Face D: {d, e, f} */ 4399 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 4400 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4401 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4402 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4403 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4404 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4405 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4406 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4407 #if 1 4408 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4409 for (p = 0; p < 3; ++p) { 4410 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4411 } 4412 #endif 4413 supportNew[0] = (c - cStart)*8 + 3; 4414 supportNew[1] = (c - cStart)*8 + 3+4; 4415 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4416 #if 1 4417 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4418 for (p = 0; p < 2; ++p) { 4419 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 4420 } 4421 #endif 4422 ++newp; 4423 /* Face E: {d, f, a} */ 4424 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4425 orntNew[0] = ornt[2] < 0 ? 0 : -2; 4426 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4427 orntNew[1] = -2; 4428 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4429 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4430 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4431 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4432 #if 1 4433 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4434 for (p = 0; p < 3; ++p) { 4435 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4436 } 4437 #endif 4438 supportNew[0] = (c - cStart)*8 + 0+4; 4439 supportNew[1] = (c - cStart)*8 + 3+4; 4440 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4441 #if 1 4442 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4443 for (p = 0; p < 2; ++p) { 4444 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 4445 } 4446 #endif 4447 ++newp; 4448 /* Face F: {c, a, f} */ 4449 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4450 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4451 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4452 orntNew[1] = 0; 4453 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4454 orntNew[2] = ornt[2] < 0 ? 0 : -2; 4455 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4456 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4457 #if 1 4458 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4459 for (p = 0; p < 3; ++p) { 4460 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4461 } 4462 #endif 4463 supportNew[0] = (c - cStart)*8 + 0+4; 4464 supportNew[1] = (c - cStart)*8 + 2+4; 4465 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4466 #if 1 4467 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4468 for (p = 0; p < 2; ++p) { 4469 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 4470 } 4471 #endif 4472 ++newp; 4473 /* Face G: {e, a, f} */ 4474 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4475 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4476 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4477 orntNew[1] = 0; 4478 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4479 orntNew[2] = ornt[3] < 0 ? 0 : -2; 4480 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4481 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4482 #if 1 4483 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4484 for (p = 0; p < 3; ++p) { 4485 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4486 } 4487 #endif 4488 supportNew[0] = (c - cStart)*8 + 1+4; 4489 supportNew[1] = (c - cStart)*8 + 3+4; 4490 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4491 #if 1 4492 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4493 for (p = 0; p < 2; ++p) { 4494 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 4495 } 4496 #endif 4497 ++newp; 4498 /* Face H: {a, b, f} */ 4499 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4500 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4501 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4502 orntNew[1] = ornt[3] < 0 ? 0 : -2; 4503 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4504 orntNew[2] = -2; 4505 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4506 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4507 #if 1 4508 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4509 for (p = 0; p < 3; ++p) { 4510 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4511 } 4512 #endif 4513 supportNew[0] = (c - cStart)*8 + 1+4; 4514 supportNew[1] = (c - cStart)*8 + 2+4; 4515 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4516 #if 1 4517 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 4518 for (p = 0; p < 2; ++p) { 4519 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 4520 } 4521 #endif 4522 ++newp; 4523 } 4524 /* Hybrid split faces have 4 edges and same cells */ 4525 for (f = fMax; f < fEnd; ++f) { 4526 const PetscInt *cone, *ornt, *support; 4527 PetscInt coneNew[4], orntNew[4]; 4528 PetscInt supportNew[2], size, s, c; 4529 4530 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4531 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4532 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4533 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4534 for (r = 0; r < 2; ++r) { 4535 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 4536 4537 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4538 orntNew[0] = ornt[0]; 4539 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4540 orntNew[1] = ornt[1]; 4541 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 4542 orntNew[2+r] = 0; 4543 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4544 orntNew[3-r] = 0; 4545 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4546 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4547 #if 1 4548 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4549 for (p = 0; p < 2; ++p) { 4550 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4551 } 4552 for (p = 2; p < 4; ++p) { 4553 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew); 4554 } 4555 #endif 4556 for (s = 0; s < size; ++s) { 4557 const PetscInt *coneCell, *orntCell, *fornt; 4558 PetscInt o, of; 4559 4560 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4561 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4562 o = orntCell[0] < 0 ? -1 : 1; 4563 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 4564 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 4565 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4566 of = fornt[c-2] < 0 ? -1 : 1; 4567 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 4568 } 4569 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4570 #if 1 4571 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 4572 for (p = 0; p < size; ++p) { 4573 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew); 4574 } 4575 #endif 4576 } 4577 } 4578 /* Hybrid cell faces have 4 edges and 2 cells */ 4579 for (c = cMax; c < cEnd; ++c) { 4580 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 4581 const PetscInt *cone, *ornt; 4582 PetscInt coneNew[4], orntNew[4]; 4583 PetscInt supportNew[2]; 4584 4585 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4586 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4587 for (r = 0; r < 3; ++r) { 4588 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 4589 orntNew[0] = 0; 4590 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 4591 orntNew[1] = 0; 4592 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 4593 orntNew[2] = 0; 4594 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 4595 orntNew[3] = 0; 4596 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4597 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4598 #if 1 4599 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew); 4600 for (p = 0; p < 2; ++p) { 4601 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 4602 } 4603 for (p = 2; p < 4; ++p) { 4604 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew); 4605 } 4606 #endif 4607 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 4608 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 4609 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4610 #if 1 4611 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew); 4612 for (p = 0; p < 2; ++p) { 4613 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew); 4614 } 4615 #endif 4616 } 4617 } 4618 /* Interior split edges have 2 vertices and the same faces as the parent */ 4619 for (e = eStart; e < eMax; ++e) { 4620 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4621 4622 for (r = 0; r < 2; ++r) { 4623 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4624 const PetscInt *cone, *ornt, *support; 4625 PetscInt coneNew[2], coneSize, c, supportSize, s; 4626 4627 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4628 coneNew[0] = vStartNew + (cone[0] - vStart); 4629 coneNew[1] = vStartNew + (cone[1] - vStart); 4630 coneNew[(r+1)%2] = newv; 4631 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4632 #if 1 4633 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4634 for (p = 0; p < 2; ++p) { 4635 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 4636 } 4637 #endif 4638 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4639 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4640 for (s = 0; s < supportSize; ++s) { 4641 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4642 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4643 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4644 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 4645 if (support[s] < fMax) { 4646 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4647 } else { 4648 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4649 } 4650 } 4651 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4652 #if 1 4653 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4654 for (p = 0; p < supportSize; ++p) { 4655 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew); 4656 } 4657 #endif 4658 } 4659 } 4660 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 4661 for (f = fStart; f < fMax; ++f) { 4662 const PetscInt *cone, *ornt, *support; 4663 PetscInt coneSize, supportSize, s; 4664 4665 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4666 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4667 for (r = 0; r < 3; ++r) { 4668 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 4669 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 4670 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 4671 -1, -1, 1, 6, 0, 4, 4672 2, 5, 3, 4, -1, -1, 4673 -1, -1, 3, 6, 2, 7}; 4674 4675 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4676 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4677 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4678 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4679 #if 1 4680 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4681 for (p = 0; p < 2; ++p) { 4682 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 4683 } 4684 #endif 4685 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4686 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4687 for (s = 0; s < supportSize; ++s) { 4688 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4689 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4690 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4691 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4692 if (support[s] < cMax) { 4693 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4694 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4695 if (er == eint[c]) { 4696 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4697 } else { 4698 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4699 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4700 } 4701 } else { 4702 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4703 } 4704 } 4705 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4706 #if 1 4707 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4708 for (p = 0; p < intFaces; ++p) { 4709 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior or hybrid face [%d, %d)", supportRef[p], fStartNew, fEndNew); 4710 } 4711 #endif 4712 } 4713 } 4714 /* Interior cell edges have 2 vertices and 4 faces */ 4715 for (c = cStart; c < cMax; ++c) { 4716 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4717 const PetscInt *cone, *ornt, *fcone; 4718 PetscInt coneNew[2], supportNew[4], find; 4719 4720 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4721 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4722 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4723 find = GetTriEdge_Static(ornt[0], 0); 4724 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4725 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4726 find = GetTriEdge_Static(ornt[2], 1); 4727 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4728 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4729 #if 1 4730 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4731 for (p = 0; p < 2; ++p) { 4732 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 4733 } 4734 #endif 4735 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4736 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4737 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4738 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4739 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4740 #if 1 4741 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 4742 for (p = 0; p < 4; ++p) { 4743 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fMaxNew); 4744 } 4745 #endif 4746 } 4747 /* Hybrid edges have two vertices and the same faces */ 4748 for (e = eMax; e < eEnd; ++e) { 4749 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4750 const PetscInt *cone, *support, *fcone; 4751 PetscInt coneNew[2], size, fsize, s; 4752 4753 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4754 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4755 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4756 coneNew[0] = vStartNew + (cone[0] - vStart); 4757 coneNew[1] = vStartNew + (cone[1] - vStart); 4758 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4759 #if 1 4760 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4761 for (p = 0; p < 2; ++p) { 4762 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 4763 } 4764 #endif 4765 for (s = 0; s < size; ++s) { 4766 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4767 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4768 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4769 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 4770 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4771 } 4772 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4773 #if 1 4774 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4775 for (p = 0; p < size; ++p) { 4776 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew); 4777 } 4778 #endif 4779 } 4780 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4781 for (f = fMax; f < fEnd; ++f) { 4782 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4783 const PetscInt *cone, *support, *ccone, *cornt; 4784 PetscInt coneNew[2], size, csize, s; 4785 4786 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4787 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4788 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4789 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4790 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4791 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4792 #if 1 4793 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4794 for (p = 0; p < 2; ++p) { 4795 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 4796 } 4797 #endif 4798 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4799 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4800 for (s = 0; s < size; ++s) { 4801 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4802 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4803 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4804 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4805 if ((c < 2) || (c >= csize)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Hybrid face %d is not in cone of hybrid cell %d", f, support[s]); 4806 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4807 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4808 } 4809 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4810 #if 1 4811 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 4812 for (p = 0; p < 2+size*2; ++p) { 4813 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew); 4814 } 4815 #endif 4816 } 4817 /* Interior vertices have identical supports */ 4818 for (v = vStart; v < vEnd; ++v) { 4819 const PetscInt newp = vStartNew + (v - vStart); 4820 const PetscInt *support, *cone; 4821 PetscInt size, s; 4822 4823 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4824 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4825 for (s = 0; s < size; ++s) { 4826 PetscInt r = 0; 4827 4828 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4829 if (cone[1] == v) r = 1; 4830 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4831 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4832 } 4833 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4834 #if 1 4835 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4836 for (p = 0; p < size; ++p) { 4837 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 4838 } 4839 #endif 4840 } 4841 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4842 for (e = eStart; e < eMax; ++e) { 4843 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4844 const PetscInt *cone, *support; 4845 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4846 4847 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4848 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4849 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4850 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4851 for (s = 0; s < size; ++s) { 4852 PetscInt r = 0; 4853 4854 if (support[s] < fMax) { 4855 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4856 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4857 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4858 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4859 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4860 faceSize += 2; 4861 } else { 4862 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4863 ++faceSize; 4864 } 4865 } 4866 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4867 for (s = 0; s < starSize*2; s += 2) { 4868 const PetscInt *cone, *ornt; 4869 PetscInt e01, e23; 4870 4871 if ((star[s] >= cStart) && (star[s] < cMax)) { 4872 /* Check edge 0-1 */ 4873 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4874 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4875 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4876 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4877 /* Check edge 2-3 */ 4878 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4879 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4880 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4881 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4882 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 4883 } 4884 } 4885 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4886 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4887 #if 1 4888 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 4889 for (p = 0; p < 2+faceSize+cellSize; ++p) { 4890 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an interior or hybrid edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 4891 } 4892 #endif 4893 } 4894 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4895 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4896 break; 4897 case REFINER_SIMPLEX_TO_HEX_3D: 4898 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4899 /* All cells have 6 faces */ 4900 for (c = cStart; c < cEnd; ++c) { 4901 const PetscInt newp = cStartNew + (c - cStart)*4; 4902 const PetscInt *cone, *ornt; 4903 PetscInt coneNew[6]; 4904 PetscInt orntNew[6]; 4905 4906 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4907 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4908 /* A hex */ 4909 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 4910 orntNew[0] = ornt[0] < 0 ? -1 : 1; 4911 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 4912 orntNew[1] = -4; 4913 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 4914 orntNew[2] = ornt[2] < 0 ? -1 : 1; 4915 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 4916 orntNew[3] = -1; 4917 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 4918 orntNew[4] = 0; 4919 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 4920 orntNew[5] = ornt[1] < 0 ? -1 : 1; 4921 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4922 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4923 #if 1 4924 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 4925 for (p = 0; p < 6; ++p) { 4926 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4927 } 4928 #endif 4929 /* B hex */ 4930 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 4931 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4932 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 4933 orntNew[1] = 0; 4934 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 4935 orntNew[2] = 0; 4936 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 4937 orntNew[3] = ornt[3] < 0 ? -2 : 0; 4938 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 4939 orntNew[4] = 0; 4940 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 4941 orntNew[5] = ornt[1] < 0 ? -4 : 2; 4942 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4943 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4944 #if 1 4945 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 4946 for (p = 0; p < 6; ++p) { 4947 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4948 } 4949 #endif 4950 /* C hex */ 4951 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 4952 orntNew[0] = ornt[0] < 0 ? -4 : 2; 4953 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 4954 orntNew[1] = -4; 4955 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 4956 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4957 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 4958 orntNew[3] = -1; 4959 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 4960 orntNew[4] = ornt[3] < 0 ? -1 : 1; 4961 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 4962 orntNew[5] = -4; 4963 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4964 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4965 #if 1 4966 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 4967 for (p = 0; p < 6; ++p) { 4968 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4969 } 4970 #endif 4971 /* D hex */ 4972 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 4973 orntNew[0] = 0; 4974 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 4975 orntNew[1] = ornt[3] < 0 ? -1 : 1; 4976 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 4977 orntNew[2] = ornt[2] < 0 ? -4 : 2; 4978 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 4979 orntNew[3] = -1; 4980 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 4981 orntNew[4] = 0; 4982 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 4983 orntNew[5] = ornt[1] < 0 ? -2 : 0; 4984 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4985 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4986 #if 1 4987 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 4988 for (p = 0; p < 6; ++p) { 4989 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 4990 } 4991 #endif 4992 } 4993 /* Split faces have 4 edges and the same cells as the parent */ 4994 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4995 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4996 for (f = fStart; f < fEnd; ++f) { 4997 const PetscInt newp = fStartNew + (f - fStart)*3; 4998 const PetscInt *cone, *ornt, *support; 4999 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5000 5001 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5002 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5003 /* A quad */ 5004 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5005 orntNew[0] = ornt[2]; 5006 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5007 orntNew[1] = ornt[0]; 5008 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5009 orntNew[2] = 0; 5010 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5011 orntNew[3] = -2; 5012 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5013 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5014 #if 1 5015 if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fEndNew); 5016 for (p = 0; p < 4; ++p) { 5017 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5018 } 5019 #endif 5020 /* B quad */ 5021 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5022 orntNew[0] = ornt[0]; 5023 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5024 orntNew[1] = ornt[1]; 5025 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5026 orntNew[2] = 0; 5027 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5028 orntNew[3] = -2; 5029 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5030 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5031 #if 1 5032 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew); 5033 for (p = 0; p < 4; ++p) { 5034 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5035 } 5036 #endif 5037 /* C quad */ 5038 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5039 orntNew[0] = ornt[1]; 5040 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5041 orntNew[1] = ornt[2]; 5042 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5043 orntNew[2] = 0; 5044 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5045 orntNew[3] = -2; 5046 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5047 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5048 #if 1 5049 if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fEndNew); 5050 for (p = 0; p < 4; ++p) { 5051 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5052 } 5053 #endif 5054 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5055 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5056 for (r = 0; r < 3; ++r) { 5057 for (s = 0; s < supportSize; ++s) { 5058 PetscInt subf; 5059 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5060 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5061 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5062 for (c = 0; c < coneSize; ++c) { 5063 if (cone[c] == f) break; 5064 } 5065 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5066 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5067 } 5068 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5069 #if 1 5070 if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fEndNew); 5071 for (p = 0; p < supportSize; ++p) { 5072 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 5073 } 5074 #endif 5075 } 5076 } 5077 /* Interior faces have 4 edges and 2 cells */ 5078 for (c = cStart; c < cEnd; ++c) { 5079 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 5080 const PetscInt *cone, *ornt; 5081 PetscInt coneNew[4], orntNew[4]; 5082 PetscInt supportNew[2]; 5083 5084 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5085 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5086 /* Face {a, g, m, h} */ 5087 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5088 orntNew[0] = 0; 5089 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5090 orntNew[1] = 0; 5091 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5092 orntNew[2] = -2; 5093 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5094 orntNew[3] = -2; 5095 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5096 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5097 #if 1 5098 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5099 for (p = 0; p < 4; ++p) { 5100 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5101 } 5102 #endif 5103 supportNew[0] = (c - cStart)*4 + 0; 5104 supportNew[1] = (c - cStart)*4 + 1; 5105 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5106 #if 1 5107 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5108 for (p = 0; p < 2; ++p) { 5109 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5110 } 5111 #endif 5112 ++newp; 5113 /* Face {g, b, l , m} */ 5114 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5115 orntNew[0] = -2; 5116 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5117 orntNew[1] = 0; 5118 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5119 orntNew[2] = 0; 5120 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5121 orntNew[3] = -2; 5122 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5123 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5124 #if 1 5125 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5126 for (p = 0; p < 4; ++p) { 5127 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5128 } 5129 #endif 5130 supportNew[0] = (c - cStart)*4 + 1; 5131 supportNew[1] = (c - cStart)*4 + 2; 5132 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5133 #if 1 5134 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5135 for (p = 0; p < 2; ++p) { 5136 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5137 } 5138 #endif 5139 ++newp; 5140 /* Face {c, g, m, i} */ 5141 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5142 orntNew[0] = 0; 5143 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5144 orntNew[1] = 0; 5145 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5146 orntNew[2] = -2; 5147 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5148 orntNew[3] = -2; 5149 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5150 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5151 #if 1 5152 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5153 for (p = 0; p < 4; ++p) { 5154 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5155 } 5156 #endif 5157 supportNew[0] = (c - cStart)*4 + 0; 5158 supportNew[1] = (c - cStart)*4 + 2; 5159 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5160 #if 1 5161 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5162 for (p = 0; p < 2; ++p) { 5163 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5164 } 5165 #endif 5166 ++newp; 5167 /* Face {d, h, m, i} */ 5168 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5169 orntNew[0] = 0; 5170 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5171 orntNew[1] = 0; 5172 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5173 orntNew[2] = -2; 5174 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5175 orntNew[3] = -2; 5176 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5177 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5178 #if 1 5179 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5180 for (p = 0; p < 4; ++p) { 5181 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5182 } 5183 #endif 5184 supportNew[0] = (c - cStart)*4 + 0; 5185 supportNew[1] = (c - cStart)*4 + 3; 5186 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5187 #if 1 5188 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5189 for (p = 0; p < 2; ++p) { 5190 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5191 } 5192 #endif 5193 ++newp; 5194 /* Face {h, m, l, e} */ 5195 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5196 orntNew[0] = 0; 5197 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5198 orntNew[1] = -2; 5199 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5200 orntNew[2] = -2; 5201 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5202 orntNew[3] = 0; 5203 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5204 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5205 #if 1 5206 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5207 for (p = 0; p < 4; ++p) { 5208 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5209 } 5210 #endif 5211 supportNew[0] = (c - cStart)*4 + 1; 5212 supportNew[1] = (c - cStart)*4 + 3; 5213 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5214 #if 1 5215 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5216 for (p = 0; p < 2; ++p) { 5217 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5218 } 5219 #endif 5220 ++newp; 5221 /* Face {i, m, l, f} */ 5222 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5223 orntNew[0] = 0; 5224 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5225 orntNew[1] = -2; 5226 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5227 orntNew[2] = -2; 5228 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5229 orntNew[3] = 0; 5230 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5231 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5232 #if 1 5233 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5234 for (p = 0; p < 4; ++p) { 5235 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5236 } 5237 #endif 5238 supportNew[0] = (c - cStart)*4 + 2; 5239 supportNew[1] = (c - cStart)*4 + 3; 5240 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5241 #if 1 5242 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5243 for (p = 0; p < 2; ++p) { 5244 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5245 } 5246 #endif 5247 ++newp; 5248 } 5249 /* Split Edges have 2 vertices and the same faces as the parent */ 5250 for (e = eStart; e < eEnd; ++e) { 5251 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5252 5253 for (r = 0; r < 2; ++r) { 5254 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5255 const PetscInt *cone, *ornt, *support; 5256 PetscInt coneNew[2], coneSize, c, supportSize, s; 5257 5258 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5259 coneNew[0] = vStartNew + (cone[0] - vStart); 5260 coneNew[1] = vStartNew + (cone[1] - vStart); 5261 coneNew[(r+1)%2] = newv; 5262 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5263 #if 1 5264 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5265 for (p = 0; p < 2; ++p) { 5266 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 5267 } 5268 #endif 5269 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5270 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5271 for (s = 0; s < supportSize; ++s) { 5272 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5273 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5274 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5275 for (c = 0; c < coneSize; ++c) { 5276 if (cone[c] == e) break; 5277 } 5278 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 5279 } 5280 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5281 #if 1 5282 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5283 for (p = 0; p < supportSize; ++p) { 5284 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 5285 } 5286 #endif 5287 } 5288 } 5289 /* Face edges have 2 vertices and 2 + cell faces supports */ 5290 for (f = fStart; f < fEnd; ++f) { 5291 const PetscInt *cone, *ornt, *support; 5292 PetscInt coneSize, supportSize, s; 5293 5294 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5295 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5296 for (r = 0; r < 3; ++r) { 5297 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 5298 PetscInt coneNew[2]; 5299 PetscInt fint[4][3] = { {0, 1, 2}, 5300 {3, 4, 0}, 5301 {2, 5, 3}, 5302 {1, 4, 5} }; 5303 5304 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5305 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5306 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 5307 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5308 #if 1 5309 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5310 for (p = 0; p < 2; ++p) { 5311 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 5312 } 5313 #endif 5314 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 5315 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 5316 for (s = 0; s < supportSize; ++s) { 5317 PetscInt er; 5318 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5319 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5320 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5321 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 5322 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 5323 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 5324 } 5325 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5326 #if 1 5327 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5328 for (p = 0; p < supportSize + 2; ++p) { 5329 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 5330 } 5331 #endif 5332 } 5333 } 5334 /* Interior cell edges have 2 vertices and 3 faces */ 5335 for (c = cStart; c < cEnd; ++c) { 5336 const PetscInt *cone; 5337 PetscInt fint[4][3] = { {0,1,2}, 5338 {0,3,4}, 5339 {2,3,5}, 5340 {1,4,5} } ; 5341 5342 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5343 for (r = 0; r < 4; r++) { 5344 PetscInt coneNew[2], supportNew[3]; 5345 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 5346 5347 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5348 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 5349 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5350 #if 1 5351 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5352 for (p = 0; p < 2; ++p) { 5353 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 5354 } 5355 #endif 5356 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 5357 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 5358 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 5359 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5360 #if 1 5361 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 5362 for (p = 0; p < 3; ++p) { 5363 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew); 5364 } 5365 #endif 5366 } 5367 } 5368 /* Old vertices have identical supports */ 5369 for (v = vStart; v < vEnd; ++v) { 5370 const PetscInt newp = vStartNew + (v - vStart); 5371 const PetscInt *support, *cone; 5372 PetscInt size, s; 5373 5374 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5375 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5376 for (s = 0; s < size; ++s) { 5377 PetscInt r = 0; 5378 5379 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5380 if (cone[1] == v) r = 1; 5381 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5382 } 5383 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5384 #if 1 5385 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5386 for (p = 0; p < size; ++p) { 5387 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 5388 } 5389 #endif 5390 } 5391 /* Edge vertices have 2 + faces supports */ 5392 for (e = eStart; e < eEnd; ++e) { 5393 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5394 const PetscInt *cone, *support; 5395 PetscInt size, s; 5396 5397 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5398 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5399 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5400 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5401 for (s = 0; s < size; ++s) { 5402 PetscInt r = 0, coneSize; 5403 5404 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5405 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5406 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 5407 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 5408 } 5409 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5410 #if 1 5411 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5412 for (p = 0; p < 2+size; ++p) { 5413 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 5414 } 5415 #endif 5416 } 5417 /* Face vertices have 3 + cells supports */ 5418 for (f = fStart; f < fEnd; ++f) { 5419 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5420 const PetscInt *cone, *support; 5421 PetscInt size, s; 5422 5423 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5424 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5425 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5426 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5427 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5428 for (s = 0; s < size; ++s) { 5429 PetscInt r = 0, coneSize; 5430 5431 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5432 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5433 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 5434 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 5435 } 5436 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5437 #if 1 5438 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5439 for (p = 0; p < 3+size; ++p) { 5440 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 5441 } 5442 #endif 5443 } 5444 /* Interior cell vertices have 4 supports */ 5445 for (c = cStart; c < cEnd; ++c) { 5446 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 5447 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5448 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5449 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5450 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5451 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5452 #if 1 5453 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 5454 for (p = 0; p < 4; ++p) { 5455 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 5456 } 5457 #endif 5458 } 5459 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5460 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5461 break; 5462 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 5463 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 5464 cMax = PetscMin(cEnd, cMax); 5465 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5466 fMax = PetscMin(fEnd, fMax); 5467 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5468 eMax = PetscMin(eEnd, eMax); 5469 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5470 /* All cells have 6 faces */ 5471 for (c = cStart; c < cMax; ++c) { 5472 const PetscInt newp = cStartNew + (c - cStart)*4; 5473 const PetscInt *cone, *ornt; 5474 PetscInt coneNew[6]; 5475 PetscInt orntNew[6]; 5476 5477 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5478 #if 1 5479 for (p = 0; p < 4; ++p) { 5480 if (cone[p] >= fMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position %D for cell %D", cone[p], p, fMax, c); 5481 } 5482 #endif 5483 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5484 /* A hex */ 5485 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5486 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5487 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5488 orntNew[1] = -4; 5489 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5490 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5491 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5492 orntNew[3] = -1; 5493 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5494 orntNew[4] = 0; 5495 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5496 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5497 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5498 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5499 #if 1 5500 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 5501 for (p = 0; p < 6; ++p) { 5502 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 5503 } 5504 #endif 5505 /* B hex */ 5506 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5507 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5508 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5509 orntNew[1] = 0; 5510 coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5511 orntNew[2] = 0; 5512 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5513 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5514 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5515 orntNew[4] = 0; 5516 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5517 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5518 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5519 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5520 #if 1 5521 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 5522 for (p = 0; p < 6; ++p) { 5523 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 5524 } 5525 #endif 5526 /* C hex */ 5527 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5528 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5529 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5530 orntNew[1] = -4; 5531 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5532 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5533 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5534 orntNew[3] = -1; 5535 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5536 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5537 coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5538 orntNew[5] = -4; 5539 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5540 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5541 #if 1 5542 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 5543 for (p = 0; p < 6; ++p) { 5544 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 5545 } 5546 #endif 5547 /* D hex */ 5548 coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5549 orntNew[0] = 0; 5550 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5551 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5552 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5553 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5554 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5555 orntNew[3] = -1; 5556 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5557 orntNew[4] = 0; 5558 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5559 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5560 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5561 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5562 #if 1 5563 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 5564 for (p = 0; p < 6; ++p) { 5565 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 5566 } 5567 #endif 5568 } 5569 for (c = cMax; c < cEnd; ++c) { 5570 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3; 5571 const PetscInt *cone, *ornt, *fornt; 5572 PetscInt coneNew[6], orntNew[6]; 5573 PetscInt o, of, cf; 5574 5575 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5576 #if 1 5577 if (cone[0] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 0 for cell %D", cone[0], fMax, c); 5578 if (cone[1] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 1 for cell %D", cone[1], fMax, c); 5579 if (cone[2] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 2 for cell %D", cone[2], fMax, c); 5580 if (cone[3] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 3 for cell %D", cone[3], fMax, c); 5581 if (cone[4] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 4 for cell %D", cone[4], fMax, c); 5582 #endif 5583 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5584 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 5585 o = ornt[0] < 0 ? -1 : 1; 5586 /* A hex */ 5587 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5588 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5589 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */ 5590 orntNew[1] = ornt[1] < 0 ? 1 : -1; 5591 cf = GetTriEdge_Static(ornt[0], 2); 5592 of = fornt[cf] < 0 ? -1 : 1; 5593 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */ 5594 orntNew[2] = o*of < 0 ? 0 : -1; 5595 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */ 5596 orntNew[3] = -1; 5597 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */ 5598 orntNew[4] = 0; 5599 cf = GetTriEdge_Static(ornt[0], 0); 5600 of = fornt[cf] < 0 ? -1 : 1; 5601 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */ 5602 orntNew[5] = o*of < 0 ? 1 : -4; 5603 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5604 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5605 #if 1 5606 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 5607 for (p = 0; p < 6; ++p) { 5608 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 5609 } 5610 #endif 5611 /* B hex */ 5612 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5613 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5614 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */ 5615 orntNew[1] = ornt[1] < 0 ? 2 : -4; 5616 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */ 5617 orntNew[2] = 0; 5618 cf = GetTriEdge_Static(ornt[0], 1); 5619 of = fornt[cf] < 0 ? -1 : 1; 5620 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */ 5621 orntNew[3] = o*of < 0 ? 0 : -1; 5622 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */ 5623 orntNew[4] = -1; 5624 cf = GetTriEdge_Static(ornt[0], 0); 5625 of = fornt[cf] < 0 ? -1 : 1; 5626 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */ 5627 orntNew[5] = o*of < 0 ? 1 : -4; 5628 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5629 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5630 #if 1 5631 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 5632 for (p = 0; p < 6; ++p) { 5633 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 5634 } 5635 #endif 5636 /* C hex */ 5637 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5638 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5639 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */ 5640 orntNew[1] = ornt[1] < 0 ? 0 : -2; 5641 cf = GetTriEdge_Static(ornt[0], 2); 5642 of = fornt[cf] < 0 ? -1 : 1; 5643 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */ 5644 orntNew[2] = o*of < 0 ? 0 : -1; 5645 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */ 5646 orntNew[3] = 0; 5647 cf = GetTriEdge_Static(ornt[0], 1); 5648 of = fornt[cf] < 0 ? -1 : 1; 5649 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */ 5650 orntNew[4] = o*of < 0 ? 0 : -1; 5651 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */ 5652 orntNew[5] = -4; 5653 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5654 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5655 #if 1 5656 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 5657 for (p = 0; p < 6; ++p) { 5658 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 5659 } 5660 #endif 5661 } 5662 5663 /* Split faces have 4 edges and the same cells as the parent */ 5664 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5665 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5666 for (f = fStart; f < fMax; ++f) { 5667 const PetscInt newp = fStartNew + (f - fStart)*3; 5668 const PetscInt *cone, *ornt, *support; 5669 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5670 5671 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5672 #if 1 5673 for (p = 0; p < 3; ++p) { 5674 if (cone[p] >= eMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid edge %D (eMax %D) in cone position %D for face %D", cone[p], p, eMax, f); 5675 } 5676 #endif 5677 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5678 /* A quad */ 5679 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5680 orntNew[0] = ornt[2]; 5681 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5682 orntNew[1] = ornt[0]; 5683 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5684 orntNew[2] = 0; 5685 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5686 orntNew[3] = -2; 5687 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5688 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5689 #if 1 5690 if ((newp+0 < fStartNew) || (newp+0 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+0, fStartNew, fEndNew); 5691 for (p = 0; p < 4; ++p) { 5692 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5693 } 5694 #endif 5695 /* B quad */ 5696 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5697 orntNew[0] = ornt[0]; 5698 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5699 orntNew[1] = ornt[1]; 5700 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5701 orntNew[2] = 0; 5702 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5703 orntNew[3] = -2; 5704 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5705 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5706 #if 1 5707 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew); 5708 for (p = 0; p < 4; ++p) { 5709 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5710 } 5711 #endif 5712 /* C quad */ 5713 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5714 orntNew[0] = ornt[1]; 5715 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5716 orntNew[1] = ornt[2]; 5717 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5718 orntNew[2] = 0; 5719 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5720 orntNew[3] = -2; 5721 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5722 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5723 #if 1 5724 if ((newp+2 < fStartNew) || (newp+2 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+2, fStartNew, fEndNew); 5725 for (p = 0; p < 4; ++p) { 5726 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5727 } 5728 #endif 5729 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5730 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5731 for (r = 0; r < 3; ++r) { 5732 for (s = 0; s < supportSize; ++s) { 5733 PetscInt subf; 5734 5735 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5736 if (coneSize != 5 && support[s] >= cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5737 if (coneSize != 4 && support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5738 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5739 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5740 for (c = 0; c < coneSize; ++c) { 5741 if (cone[c] == f) break; 5742 } 5743 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5744 if (coneSize == 4) { 5745 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5746 } else if (coneSize == 5) { 5747 if (c != 0 && c != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position %D in cone %D of cell %D (cMax %D) for face %D", c, support[s], cMax, f); 5748 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf; 5749 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5750 } 5751 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5752 #if 1 5753 if ((newp+r < fStartNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+r, fStartNew, fEndNew); 5754 for (p = 0; p < supportSize; ++p) { 5755 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 5756 } 5757 #endif 5758 } 5759 } 5760 /* Interior faces have 4 edges and 2 cells */ 5761 for (c = cStart; c < cMax; ++c) { 5762 PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6; 5763 const PetscInt *cone, *ornt; 5764 PetscInt coneNew[4], orntNew[4]; 5765 PetscInt supportNew[2]; 5766 5767 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5768 #if 1 5769 for (p = 0; p < 4; ++p) { 5770 if (cone[p] >= fMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position %D for face %D", cone[p], p, fMax, f); 5771 } 5772 #endif 5773 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5774 /* Face {a, g, m, h} */ 5775 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5776 orntNew[0] = 0; 5777 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5778 orntNew[1] = 0; 5779 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5780 orntNew[2] = -2; 5781 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5782 orntNew[3] = -2; 5783 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5784 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5785 #if 1 5786 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5787 for (p = 0; p < 4; ++p) { 5788 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5789 } 5790 #endif 5791 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5792 supportNew[1] = cStartNew + (c - cStart)*4 + 1; 5793 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5794 #if 1 5795 for (p = 0; p < 2; ++p) { 5796 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5797 } 5798 #endif 5799 ++newp; 5800 /* Face {g, b, l , m} */ 5801 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5802 orntNew[0] = -2; 5803 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5804 orntNew[1] = 0; 5805 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5806 orntNew[2] = 0; 5807 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5808 orntNew[3] = -2; 5809 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5810 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5811 #if 1 5812 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5813 for (p = 0; p < 4; ++p) { 5814 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5815 } 5816 #endif 5817 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5818 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5819 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5820 #if 1 5821 for (p = 0; p < 2; ++p) { 5822 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5823 } 5824 #endif 5825 ++newp; 5826 /* Face {c, g, m, i} */ 5827 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5828 orntNew[0] = 0; 5829 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5830 orntNew[1] = 0; 5831 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5832 orntNew[2] = -2; 5833 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5834 orntNew[3] = -2; 5835 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5836 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5837 #if 1 5838 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5839 for (p = 0; p < 4; ++p) { 5840 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5841 } 5842 #endif 5843 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5844 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5845 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5846 #if 1 5847 for (p = 0; p < 2; ++p) { 5848 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5849 } 5850 #endif 5851 ++newp; 5852 /* Face {d, h, m, i} */ 5853 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5854 orntNew[0] = 0; 5855 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5856 orntNew[1] = 0; 5857 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5858 orntNew[2] = -2; 5859 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5860 orntNew[3] = -2; 5861 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5862 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5863 #if 1 5864 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5865 for (p = 0; p < 4; ++p) { 5866 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5867 } 5868 #endif 5869 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5870 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5871 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5872 #if 1 5873 for (p = 0; p < 2; ++p) { 5874 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5875 } 5876 #endif 5877 ++newp; 5878 /* Face {h, m, l, e} */ 5879 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5880 orntNew[0] = 0; 5881 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5882 orntNew[1] = -2; 5883 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5884 orntNew[2] = -2; 5885 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5886 orntNew[3] = 0; 5887 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5888 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5889 #if 1 5890 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5891 for (p = 0; p < 4; ++p) { 5892 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5893 } 5894 #endif 5895 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5896 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5897 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5898 #if 1 5899 for (p = 0; p < 2; ++p) { 5900 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5901 } 5902 #endif 5903 ++newp; 5904 /* Face {i, m, l, f} */ 5905 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5906 orntNew[0] = 0; 5907 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5908 orntNew[1] = -2; 5909 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5910 orntNew[2] = -2; 5911 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5912 orntNew[3] = 0; 5913 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5914 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5915 #if 1 5916 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5917 for (p = 0; p < 4; ++p) { 5918 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5919 } 5920 #endif 5921 supportNew[0] = cStartNew + (c - cStart)*4 + 2; 5922 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5923 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5924 #if 1 5925 for (p = 0; p < 2; ++p) { 5926 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 5927 } 5928 #endif 5929 ++newp; 5930 } 5931 /* Hybrid split faces have 4 edges and same cells */ 5932 for (f = fMax; f < fEnd; ++f) { 5933 const PetscInt *cone, *ornt, *support; 5934 PetscInt coneNew[4], orntNew[4]; 5935 PetscInt size, s; 5936 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2; 5937 5938 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5939 #if 1 5940 if (cone[0] >= eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid edge %D (eMax %D) in cone position 0 for face %D", cone[0], eMax, f); 5941 if (cone[1] >= eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid edge %D (eMax %D) in cone position 1 for face %D", cone[1], eMax, f); 5942 if (cone[2] < eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected edge %D (eMax %D) in cone position 2 for face %D", cone[2], eMax, f); 5943 if (cone[3] < eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected edge %D (eMax %D) in cone position 3 for face %D", cone[3], eMax, f); 5944 #endif 5945 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5946 /* A face */ 5947 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5948 orntNew[0] = ornt[0]; 5949 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 5950 orntNew[1] = 0; 5951 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5952 orntNew[2] = ornt[1] < 0 ? 0 : -2; 5953 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax); 5954 orntNew[3] = ornt[2] < 0 ? 0 : -2; 5955 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5956 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5957 #if 1 5958 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 5959 for (p = 0; p < 4; ++p) { 5960 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5961 } 5962 #endif 5963 5964 /* B face */ 5965 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5966 orntNew[0] = ornt[0]; 5967 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax); 5968 orntNew[1] = ornt[3]; 5969 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5970 orntNew[2] = ornt[1] < 0 ? 0 : -2; 5971 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 5972 orntNew[3] = -2; 5973 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5974 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5975 #if 1 5976 if ((newp+1 < fStartNew) || (newp+1 >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp+1, fStartNew, fEndNew); 5977 for (p = 0; p < 4; ++p) { 5978 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 5979 } 5980 #endif 5981 5982 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5983 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5984 for (r = 0; r < 2; ++r) { 5985 for (s = 0; s < size; ++s) { 5986 const PetscInt *coneCell, *orntCell, *fornt; 5987 PetscInt coneSize, o, of, c; 5988 5989 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5990 if (coneSize != 5 || support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5991 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 5992 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 5993 o = orntCell[0] < 0 ? -1 : 1; 5994 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 5995 if (c == 0 || c == 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of cell %D (cMax %D) for face %D", c, support[s], cMax, f); 5996 if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 5997 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 5998 of = fornt[c-2] < 0 ? -1 : 1; 5999 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 6000 } 6001 ierr = DMPlexSetSupport(rdm, newp + r, supportRef);CHKERRQ(ierr); 6002 #if 1 6003 for (p = 0; p < size; ++p) { 6004 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 6005 } 6006 #endif 6007 } 6008 } 6009 /* Interior hybrid faces have 4 edges and 2 cells */ 6010 for (c = cMax; c < cEnd; ++c) { 6011 PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3; 6012 const PetscInt *cone, *ornt; 6013 PetscInt coneNew[4], orntNew[4]; 6014 PetscInt supportNew[2]; 6015 6016 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6017 #if 1 6018 if (cone[0] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 0 for cell %D", cone[0], fMax, c); 6019 if (cone[1] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 1 for cell %D", cone[1], fMax, c); 6020 if (cone[2] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 2 for cell %D", cone[2], fMax, c); 6021 if (cone[3] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 3 for cell %D", cone[3], fMax, c); 6022 if (cone[4] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected face %D (fMax %D) in cone position 3 for cell %D", cone[3], fMax, c); 6023 #endif 6024 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6025 /* Face {a, g, h, d} */ 6026 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 6027 orntNew[0] = 0; 6028 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6029 orntNew[1] = 0; 6030 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 6031 orntNew[2] = -2; 6032 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax); 6033 orntNew[3] = -2; 6034 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6035 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6036 #if 1 6037 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6038 for (p = 0; p < 4; ++p) { 6039 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6040 } 6041 #endif 6042 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6043 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6044 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6045 #if 1 6046 for (p = 0; p < 2; ++p) { 6047 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 6048 } 6049 #endif 6050 ++newp; 6051 /* Face {b, g, h, l} */ 6052 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 6053 orntNew[0] = 0; 6054 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6055 orntNew[1] = 0; 6056 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6057 orntNew[2] = -2; 6058 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax); 6059 orntNew[3] = -2; 6060 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6061 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6062 #if 1 6063 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6064 for (p = 0; p < 4; ++p) { 6065 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6066 } 6067 #endif 6068 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6069 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6070 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6071 #if 1 6072 for (p = 0; p < 2; ++p) { 6073 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 6074 } 6075 #endif 6076 ++newp; 6077 /* Face {c, g, h, f} */ 6078 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 6079 orntNew[0] = 0; 6080 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6081 orntNew[1] = 0; 6082 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 6083 orntNew[2] = -2; 6084 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax); 6085 orntNew[3] = -2; 6086 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6087 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6088 #if 1 6089 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6090 for (p = 0; p < 4; ++p) { 6091 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6092 } 6093 #endif 6094 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6095 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6096 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6097 #if 1 6098 for (p = 0; p < 2; ++p) { 6099 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 6100 } 6101 #endif 6102 } 6103 /* Face edges have 2 vertices and 2 + cell faces supports */ 6104 for (f = fStart; f < fMax; ++f) { 6105 const PetscInt *cone, *ornt, *support; 6106 PetscInt coneSize, supportSize, s; 6107 6108 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6109 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6110 for (r = 0; r < 3; ++r) { 6111 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 6112 PetscInt coneNew[2]; 6113 PetscInt fint[4][3] = { {0, 1, 2}, 6114 {3, 4, 0}, 6115 {2, 5, 3}, 6116 {1, 4, 5} }; 6117 6118 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6119 if (cone[r] >= eMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone point %D in position %D for face %D (eMax %D)", cone[r], r, f, eMax); 6120 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6121 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 6122 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6123 #if 1 6124 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6125 for (p = 0; p < 2; ++p) { 6126 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 6127 } 6128 #endif 6129 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 6130 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 6131 for (s = 0; s < supportSize; ++s) { 6132 PetscInt er; 6133 6134 supportRef[2+s] = -1; 6135 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6136 if (coneSize != 5 && support[s] >= cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6137 if (coneSize != 4 && support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6138 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6139 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6140 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6141 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 6142 if (coneSize == 4) { 6143 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 6144 } else if (coneSize == 5) { 6145 if (c != 0 && c != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position %D in cone %D of cell %D (cMax %D) for face %D", c, support[s], cMax, f); 6146 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er; 6147 } 6148 } 6149 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6150 #if 1 6151 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6152 for (p = 0; p < supportSize + 2; ++p) { 6153 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 6154 } 6155 #endif 6156 } 6157 } 6158 /* Interior cell edges have 2 vertices and 3 faces */ 6159 for (c = cStart; c < cMax; ++c) { 6160 const PetscInt *cone; 6161 PetscInt fint[4][3] = { {0,1,2}, 6162 {0,3,4}, 6163 {2,3,5}, 6164 {1,4,5} } ; 6165 6166 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6167 for (r = 0; r < 4; r++) { 6168 PetscInt coneNew[2], supportNew[3]; 6169 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 6170 6171 if (cone[r] >= fMax) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position %D for cell %D", cone[r], r, fMax, c); 6172 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6173 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart; 6174 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6175 #if 1 6176 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6177 for (p = 0; p < 2; ++p) { 6178 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 6179 } 6180 #endif 6181 supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0]; 6182 supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1]; 6183 supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2]; 6184 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6185 #if 1 6186 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6187 for (p = 0; p < 3; ++p) { 6188 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew); 6189 } 6190 #endif 6191 } 6192 } 6193 /* Hybrid edges have two vertices and the same faces */ 6194 for (e = eMax; e < eEnd; ++e) { 6195 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 6196 const PetscInt *cone, *support, *fcone; 6197 PetscInt coneNew[2], size, fsize, s; 6198 6199 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6200 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6201 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6202 coneNew[0] = vStartNew + (cone[0] - vStart); 6203 coneNew[1] = vStartNew + (cone[1] - vStart); 6204 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6205 #if 1 6206 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is a edge [%d, %d)", newp, eStartNew, eEndNew); 6207 for (p = 0; p < 2; ++p) { 6208 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 6209 } 6210 #endif 6211 for (s = 0; s < size; ++s) { 6212 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6213 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6214 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6215 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 6216 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2; 6217 } 6218 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6219 #if 1 6220 for (p = 0; p < size; ++p) { 6221 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 6222 } 6223 #endif 6224 } 6225 /* Hybrid face edges have 2 vertices and 2 + cell faces supports */ 6226 for (f = fMax; f < fEnd; ++f) { 6227 const PetscInt *cone, *ornt, *support; 6228 PetscInt coneSize, supportSize; 6229 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax; 6230 PetscInt coneNew[2], s; 6231 6232 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6233 #if 1 6234 if (cone[0] >= eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone point %D in position 0 for face %D (eMax %D)", cone[0], f, eMax); 6235 if (cone[1] >= eMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone point %D in position 1 for face %D (eMax %D)", cone[1], f, eMax); 6236 #endif 6237 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6238 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6239 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6240 #if 1 6241 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6242 for (p = 0; p < 2; ++p) { 6243 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 6244 } 6245 #endif 6246 supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0; 6247 supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1; 6248 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6249 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6250 for (s = 0; s < supportSize; ++s) { 6251 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6252 if (coneSize != 5 || support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6253 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6254 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6255 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6256 if (c == 0 || c == 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of cell %D (cMax %D) for face %D", c, support[s], cMax, f); 6257 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2; 6258 } 6259 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6260 #if 1 6261 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6262 for (p = 0; p < supportSize + 2; ++p) { 6263 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 6264 } 6265 #endif 6266 } 6267 /* Hybrid cell edges have 2 vertices and 3 faces */ 6268 for (c = cMax; c < cEnd; ++c) { 6269 PetscInt coneNew[2], supportNew[3]; 6270 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6271 const PetscInt *cone; 6272 6273 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6274 #if 1 6275 if (cone[0] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 0 for cell %D", cone[0], fMax, c); 6276 if (cone[1] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected hybrid face %D (fMax %D) in cone position 1 for cell %D", cone[1], fMax, c); 6277 #endif 6278 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6279 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6280 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6281 #if 1 6282 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6283 for (p = 0; p < 2; ++p) { 6284 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 6285 } 6286 #endif 6287 supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 6288 supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 6289 supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 6290 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6291 #if 1 6292 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6293 for (p = 0; p < 3; ++p) { 6294 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew); 6295 } 6296 #endif 6297 } 6298 /* Old vertices have identical supports */ 6299 for (v = vStart; v < vEnd; ++v) { 6300 const PetscInt newp = vStartNew + (v - vStart); 6301 const PetscInt *support, *cone; 6302 PetscInt size, s; 6303 6304 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6305 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6306 for (s = 0; s < size; ++s) { 6307 const PetscInt e = support[s]; 6308 6309 supportRef[s] = -1; 6310 if (eStart <= e) { 6311 if (e < eMax) { 6312 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6313 supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0); 6314 } else if (e < eEnd) { 6315 supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax; 6316 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", e, eStart, eEnd); 6317 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", e, eStart, eEnd); 6318 } 6319 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6320 #if 1 6321 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6322 for (p = 0; p < size; ++p) { 6323 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 6324 } 6325 #endif 6326 } 6327 /* Interior edge vertices have 2 + faces supports */ 6328 for (e = eStart; e < eMax; ++e) { 6329 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6330 const PetscInt *cone, *support; 6331 PetscInt size, s; 6332 6333 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6334 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6335 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6336 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6337 for (s = 0; s < size; ++s) { 6338 PetscInt r, coneSize; 6339 6340 supportRef[2+s] = -1; 6341 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6342 if (coneSize != 4 && support[s] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6343 if (coneSize != 3 && support[s] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6344 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6345 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 6346 if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r; 6347 else if (coneSize == 4) { 6348 if (r != 0 && r != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of face %D (fMax %D) for edge %D", r, support[s], fMax, e); 6349 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax; 6350 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6351 } 6352 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6353 #if 1 6354 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6355 for (p = 0; p < 2+size; ++p) { 6356 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 6357 } 6358 #endif 6359 } 6360 /* Split Edges have 2 vertices and the same faces as the parent */ 6361 for (e = eStart; e < eMax; ++e) { 6362 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6363 6364 for (r = 0; r < 2; ++r) { 6365 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6366 const PetscInt *cone, *ornt, *support; 6367 PetscInt coneNew[2], coneSize, c, supportSize, s; 6368 6369 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6370 coneNew[0] = vStartNew + (cone[0] - vStart); 6371 coneNew[1] = vStartNew + (cone[1] - vStart); 6372 coneNew[(r+1)%2] = newv; 6373 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6374 #if 1 6375 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6376 for (p = 0; p < 2; ++p) { 6377 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 6378 } 6379 #endif 6380 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6381 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6382 for (s = 0; s < supportSize; ++s) { 6383 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6384 if (coneSize != 4 && support[s] >= fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6385 if (coneSize != 3 && support[s] < fMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6386 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6387 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6388 for (c = 0; c < coneSize; ++c) { 6389 if (cone[c] == e) break; 6390 } 6391 if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 6392 else if (coneSize == 4) { 6393 if (c != 0 && c != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of face %D (fMax %D) for edge %D", c, support[s], fMax, e); 6394 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6395 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6396 } 6397 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6398 #if 1 6399 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6400 for (p = 0; p < supportSize; ++p) { 6401 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 6402 } 6403 #endif 6404 } 6405 } 6406 /* Face vertices have 3 + cells supports */ 6407 for (f = fStart; f < fMax; ++f) { 6408 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6409 const PetscInt *cone, *support; 6410 PetscInt size, s; 6411 6412 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6413 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6414 supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 6415 supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 6416 supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 6417 for (s = 0; s < size; ++s) { 6418 PetscInt r, coneSize; 6419 6420 supportRef[3+s] = -1; 6421 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6422 if (coneSize != 5 && support[s] >= cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6423 if (coneSize != 4 && support[s] < cMax) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 6424 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6425 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 6426 if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r; 6427 else if (coneSize == 5) { 6428 if (r != 0 && r != 1) SETERRQ4(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected position in cone %D of cell %D (cMax %D) for face %D", r, support[s], cMax, f); 6429 supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax; 6430 } 6431 } 6432 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6433 #if 1 6434 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6435 for (p = 0; p < 3+size; ++p) { 6436 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 6437 } 6438 #endif 6439 } 6440 /* Interior cell vertices have 4 supports */ 6441 for (c = cStart; c < cMax; ++c) { 6442 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 6443 6444 supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 6445 supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6446 supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6447 supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6448 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6449 #if 1 6450 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 6451 for (p = 0; p < 4; ++p) { 6452 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 6453 } 6454 #endif 6455 } 6456 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6457 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 6458 break; 6459 case REFINER_HEX_3D: 6460 /* 6461 Bottom (viewed from top) Top 6462 1---------2---------2 7---------2---------6 6463 | | | | | | 6464 | B 2 C | | H 2 G | 6465 | | | | | | 6466 3----3----0----1----1 3----3----0----1----1 6467 | | | | | | 6468 | A 0 D | | E 0 F | 6469 | | | | | | 6470 0---------0---------3 4---------0---------5 6471 */ 6472 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 6473 for (c = cStart; c < cEnd; ++c) { 6474 const PetscInt newp = (c - cStart)*8; 6475 const PetscInt *cone, *ornt; 6476 PetscInt coneNew[6], orntNew[6]; 6477 6478 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6479 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6480 /* A hex */ 6481 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 6482 orntNew[0] = ornt[0]; 6483 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6484 orntNew[1] = 0; 6485 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 6486 orntNew[2] = ornt[2]; 6487 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6488 orntNew[3] = 0; 6489 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6490 orntNew[4] = 0; 6491 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 6492 orntNew[5] = ornt[5]; 6493 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 6494 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 6495 #if 1 6496 if ((newp+0 < cStartNew) || (newp+0 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cEndNew); 6497 for (p = 0; p < 6; ++p) { 6498 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 6499 } 6500 #endif 6501 /* B hex */ 6502 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 6503 orntNew[0] = ornt[0]; 6504 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6505 orntNew[1] = 0; 6506 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6507 orntNew[2] = -1; 6508 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 6509 orntNew[3] = ornt[3]; 6510 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6511 orntNew[4] = 0; 6512 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 6513 orntNew[5] = ornt[5]; 6514 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6515 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6516 #if 1 6517 if ((newp+1 < cStartNew) || (newp+1 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cEndNew); 6518 for (p = 0; p < 6; ++p) { 6519 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 6520 } 6521 #endif 6522 /* C hex */ 6523 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 6524 orntNew[0] = ornt[0]; 6525 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6526 orntNew[1] = 0; 6527 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6528 orntNew[2] = -1; 6529 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 6530 orntNew[3] = ornt[3]; 6531 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 6532 orntNew[4] = ornt[4]; 6533 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6534 orntNew[5] = -4; 6535 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 6536 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 6537 #if 1 6538 if ((newp+2 < cStartNew) || (newp+2 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cEndNew); 6539 for (p = 0; p < 6; ++p) { 6540 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 6541 } 6542 #endif 6543 /* D hex */ 6544 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 6545 orntNew[0] = ornt[0]; 6546 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6547 orntNew[1] = 0; 6548 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 6549 orntNew[2] = ornt[2]; 6550 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6551 orntNew[3] = 0; 6552 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 6553 orntNew[4] = ornt[4]; 6554 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6555 orntNew[5] = -4; 6556 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 6557 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 6558 #if 1 6559 if ((newp+3 < cStartNew) || (newp+3 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cEndNew); 6560 for (p = 0; p < 6; ++p) { 6561 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 6562 } 6563 #endif 6564 /* E hex */ 6565 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6566 orntNew[0] = -4; 6567 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 6568 orntNew[1] = ornt[1]; 6569 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 6570 orntNew[2] = ornt[2]; 6571 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6572 orntNew[3] = 0; 6573 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6574 orntNew[4] = -1; 6575 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 6576 orntNew[5] = ornt[5]; 6577 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 6578 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 6579 #if 1 6580 if ((newp+4 < cStartNew) || (newp+4 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cEndNew); 6581 for (p = 0; p < 6; ++p) { 6582 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 6583 } 6584 #endif 6585 /* F hex */ 6586 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6587 orntNew[0] = -4; 6588 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 6589 orntNew[1] = ornt[1]; 6590 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 6591 orntNew[2] = ornt[2]; 6592 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6593 orntNew[3] = -1; 6594 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 6595 orntNew[4] = ornt[4]; 6596 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6597 orntNew[5] = 1; 6598 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 6599 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 6600 #if 1 6601 if ((newp+5 < cStartNew) || (newp+5 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cEndNew); 6602 for (p = 0; p < 6; ++p) { 6603 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 6604 } 6605 #endif 6606 /* G hex */ 6607 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6608 orntNew[0] = -4; 6609 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 6610 orntNew[1] = ornt[1]; 6611 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6612 orntNew[2] = 0; 6613 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 6614 orntNew[3] = ornt[3]; 6615 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 6616 orntNew[4] = ornt[4]; 6617 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6618 orntNew[5] = -3; 6619 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 6620 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 6621 #if 1 6622 if ((newp+6 < cStartNew) || (newp+6 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cEndNew); 6623 for (p = 0; p < 6; ++p) { 6624 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 6625 } 6626 #endif 6627 /* H hex */ 6628 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6629 orntNew[0] = -4; 6630 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 6631 orntNew[1] = ornt[1]; 6632 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6633 orntNew[2] = -1; 6634 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 6635 orntNew[3] = ornt[3]; 6636 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6637 orntNew[4] = 3; 6638 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 6639 orntNew[5] = ornt[5]; 6640 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 6641 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 6642 #if 1 6643 if ((newp+7 < cStartNew) || (newp+7 >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cEndNew); 6644 for (p = 0; p < 6; ++p) { 6645 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fEndNew); 6646 } 6647 #endif 6648 } 6649 /* Split faces have 4 edges and the same cells as the parent */ 6650 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6651 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 6652 for (f = fStart; f < fEnd; ++f) { 6653 for (r = 0; r < 4; ++r) { 6654 /* TODO: This can come from GetFaces_Internal() */ 6655 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}; 6656 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 6657 const PetscInt *cone, *ornt, *support; 6658 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 6659 6660 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6661 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6662 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 6663 orntNew[(r+3)%4] = ornt[(r+3)%4]; 6664 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 6665 orntNew[(r+0)%4] = ornt[r]; 6666 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6667 orntNew[(r+1)%4] = 0; 6668 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 6669 orntNew[(r+2)%4] = -2; 6670 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6671 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6672 #if 1 6673 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6674 for (p = 0; p < 4; ++p) { 6675 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6676 } 6677 #endif 6678 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6679 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6680 for (s = 0; s < supportSize; ++s) { 6681 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6682 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6683 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6684 for (c = 0; c < coneSize; ++c) { 6685 if (cone[c] == f) break; 6686 } 6687 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 6688 } 6689 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6690 #if 1 6691 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6692 for (p = 0; p < supportSize; ++p) { 6693 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 6694 } 6695 #endif 6696 } 6697 } 6698 /* Interior faces have 4 edges and 2 cells */ 6699 for (c = cStart; c < cEnd; ++c) { 6700 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}; 6701 const PetscInt *cone, *ornt; 6702 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 6703 6704 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6705 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6706 /* A-D face */ 6707 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 6708 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 6709 orntNew[0] = 0; 6710 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6711 orntNew[1] = 0; 6712 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6713 orntNew[2] = -2; 6714 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 6715 orntNew[3] = -2; 6716 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6717 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6718 #if 1 6719 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6720 for (p = 0; p < 4; ++p) { 6721 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6722 } 6723 #endif 6724 /* C-D face */ 6725 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 6726 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 6727 orntNew[0] = 0; 6728 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6729 orntNew[1] = 0; 6730 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6731 orntNew[2] = -2; 6732 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 6733 orntNew[3] = -2; 6734 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6735 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6736 #if 1 6737 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6738 for (p = 0; p < 4; ++p) { 6739 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6740 } 6741 #endif 6742 /* B-C face */ 6743 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 6744 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 6745 orntNew[0] = -2; 6746 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 6747 orntNew[1] = 0; 6748 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6749 orntNew[2] = 0; 6750 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6751 orntNew[3] = -2; 6752 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6753 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6754 #if 1 6755 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6756 for (p = 0; p < 4; ++p) { 6757 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6758 } 6759 #endif 6760 /* A-B face */ 6761 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 6762 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 6763 orntNew[0] = -2; 6764 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 6765 orntNew[1] = 0; 6766 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6767 orntNew[2] = 0; 6768 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6769 orntNew[3] = -2; 6770 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6771 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6772 #if 1 6773 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6774 for (p = 0; p < 4; ++p) { 6775 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6776 } 6777 #endif 6778 /* E-F face */ 6779 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 6780 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6781 orntNew[0] = -2; 6782 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 6783 orntNew[1] = -2; 6784 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 6785 orntNew[2] = 0; 6786 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6787 orntNew[3] = 0; 6788 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6789 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6790 #if 1 6791 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6792 for (p = 0; p < 4; ++p) { 6793 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6794 } 6795 #endif 6796 /* F-G face */ 6797 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 6798 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6799 orntNew[0] = -2; 6800 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 6801 orntNew[1] = -2; 6802 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 6803 orntNew[2] = 0; 6804 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6805 orntNew[3] = 0; 6806 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6807 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6808 #if 1 6809 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6810 for (p = 0; p < 4; ++p) { 6811 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6812 } 6813 #endif 6814 /* G-H face */ 6815 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 6816 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 6817 orntNew[0] = -2; 6818 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 6819 orntNew[1] = 0; 6820 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6821 orntNew[2] = 0; 6822 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6823 orntNew[3] = -2; 6824 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6825 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6826 #if 1 6827 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6828 for (p = 0; p < 4; ++p) { 6829 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6830 } 6831 #endif 6832 /* E-H face */ 6833 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 6834 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6835 orntNew[0] = -2; 6836 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 6837 orntNew[1] = -2; 6838 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 6839 orntNew[2] = 0; 6840 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6841 orntNew[3] = 0; 6842 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6843 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6844 #if 1 6845 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6846 for (p = 0; p < 4; ++p) { 6847 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6848 } 6849 #endif 6850 /* A-E face */ 6851 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 6852 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 6853 orntNew[0] = 0; 6854 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6855 orntNew[1] = 0; 6856 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6857 orntNew[2] = -2; 6858 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 6859 orntNew[3] = -2; 6860 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6861 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6862 #if 1 6863 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6864 for (p = 0; p < 4; ++p) { 6865 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6866 } 6867 #endif 6868 /* D-F face */ 6869 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 6870 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 6871 orntNew[0] = -2; 6872 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 6873 orntNew[1] = 0; 6874 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6875 orntNew[2] = 0; 6876 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6877 orntNew[3] = -2; 6878 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6879 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6880 #if 1 6881 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6882 for (p = 0; p < 4; ++p) { 6883 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6884 } 6885 #endif 6886 /* C-G face */ 6887 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 6888 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6889 orntNew[0] = -2; 6890 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 6891 orntNew[1] = -2; 6892 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 6893 orntNew[2] = 0; 6894 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6895 orntNew[3] = 0; 6896 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6897 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6898 #if 1 6899 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6900 for (p = 0; p < 4; ++p) { 6901 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6902 } 6903 #endif 6904 /* B-H face */ 6905 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 6906 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6907 orntNew[0] = 0; 6908 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6909 orntNew[1] = -2; 6910 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 6911 orntNew[2] = -2; 6912 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 6913 orntNew[3] = 0; 6914 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6915 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6916 #if 1 6917 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6918 for (p = 0; p < 4; ++p) { 6919 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eEndNew); 6920 } 6921 #endif 6922 for (r = 0; r < 12; ++r) { 6923 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 6924 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 6925 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 6926 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6927 #if 1 6928 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fEndNew); 6929 for (p = 0; p < 2; ++p) { 6930 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cEndNew); 6931 } 6932 #endif 6933 } 6934 } 6935 /* Split edges have 2 vertices and the same faces as the parent */ 6936 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6937 for (e = eStart; e < eEnd; ++e) { 6938 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6939 6940 for (r = 0; r < 2; ++r) { 6941 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6942 const PetscInt *cone, *ornt, *support; 6943 PetscInt coneNew[2], coneSize, c, supportSize, s; 6944 6945 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6946 coneNew[0] = vStartNew + (cone[0] - vStart); 6947 coneNew[1] = vStartNew + (cone[1] - vStart); 6948 coneNew[(r+1)%2] = newv; 6949 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6950 #if 1 6951 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6952 for (p = 0; p < 2; ++p) { 6953 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 6954 } 6955 #endif 6956 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6957 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6958 for (s = 0; s < supportSize; ++s) { 6959 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6960 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6961 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6962 for (c = 0; c < coneSize; ++c) { 6963 if (cone[c] == e) break; 6964 } 6965 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 6966 } 6967 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6968 #if 1 6969 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6970 for (p = 0; p < supportSize; ++p) { 6971 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 6972 } 6973 #endif 6974 } 6975 } 6976 /* Face edges have 2 vertices and 2+cells faces */ 6977 for (f = fStart; f < fEnd; ++f) { 6978 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}; 6979 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 6980 const PetscInt *cone, *coneCell, *orntCell, *support; 6981 PetscInt coneNew[2], coneSize, c, supportSize, s; 6982 6983 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6984 for (r = 0; r < 4; ++r) { 6985 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6986 6987 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6988 coneNew[1] = newv; 6989 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6990 #if 1 6991 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 6992 for (p = 0; p < 2; ++p) { 6993 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 6994 } 6995 #endif 6996 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6997 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6998 supportRef[0] = fStartNew + (f - fStart)*4 + r; 6999 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7000 for (s = 0; s < supportSize; ++s) { 7001 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7002 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7003 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7004 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7005 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7006 } 7007 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7008 #if 1 7009 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 7010 for (p = 0; p < 2+supportSize; ++p) { 7011 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 7012 } 7013 #endif 7014 } 7015 } 7016 /* Cell edges have 2 vertices and 4 faces */ 7017 for (c = cStart; c < cEnd; ++c) { 7018 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}; 7019 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7020 const PetscInt *cone; 7021 PetscInt coneNew[2], supportNew[4]; 7022 7023 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7024 for (r = 0; r < 6; ++r) { 7025 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7026 7027 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 7028 coneNew[1] = newv; 7029 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7030 #if 1 7031 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 7032 for (p = 0; p < 2; ++p) { 7033 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 7034 } 7035 #endif 7036 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7037 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7038 #if 1 7039 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eEndNew); 7040 for (p = 0; p < 4; ++p) { 7041 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fEndNew); 7042 } 7043 #endif 7044 } 7045 } 7046 /* Old vertices have identical supports */ 7047 for (v = vStart; v < vEnd; ++v) { 7048 const PetscInt newp = vStartNew + (v - vStart); 7049 const PetscInt *support, *cone; 7050 PetscInt size, s; 7051 7052 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 7053 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 7054 for (s = 0; s < size; ++s) { 7055 PetscInt r = 0; 7056 7057 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7058 if (cone[1] == v) r = 1; 7059 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 7060 } 7061 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7062 #if 1 7063 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 7064 for (p = 0; p < size; ++p) { 7065 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 7066 } 7067 #endif 7068 } 7069 /* Edge vertices have 2 + faces supports */ 7070 for (e = eStart; e < eEnd; ++e) { 7071 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 7072 const PetscInt *cone, *support; 7073 PetscInt size, s; 7074 7075 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7076 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7077 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 7078 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 7079 for (s = 0; s < size; ++s) { 7080 PetscInt r; 7081 7082 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7083 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 7084 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 7085 } 7086 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7087 #if 1 7088 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 7089 for (p = 0; p < 2+size; ++p) { 7090 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 7091 } 7092 #endif 7093 } 7094 /* Face vertices have 4 + cells supports */ 7095 for (f = fStart; f < fEnd; ++f) { 7096 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7097 const PetscInt *cone, *support; 7098 PetscInt size, s; 7099 7100 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7101 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7102 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7103 for (s = 0; s < size; ++s) { 7104 PetscInt r; 7105 7106 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7107 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 7108 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 7109 } 7110 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7111 #if 1 7112 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 7113 for (p = 0; p < 4+size; ++p) { 7114 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 7115 } 7116 #endif 7117 } 7118 /* Cell vertices have 6 supports */ 7119 for (c = cStart; c < cEnd; ++c) { 7120 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7121 PetscInt supportNew[6]; 7122 7123 for (r = 0; r < 6; ++r) { 7124 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7125 } 7126 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7127 } 7128 ierr = PetscFree(supportRef);CHKERRQ(ierr); 7129 break; 7130 case REFINER_HYBRID_HEX_3D: 7131 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 7132 /* 7133 Bottom (viewed from top) Top 7134 1---------2---------2 7---------2---------6 7135 | | | | | | 7136 | B 2 C | | H 2 G | 7137 | | | | | | 7138 3----3----0----1----1 3----3----0----1----1 7139 | | | | | | 7140 | A 0 D | | E 0 F | 7141 | | | | | | 7142 0---------0---------3 4---------0---------5 7143 */ 7144 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 7145 for (c = cStart; c < cMax; ++c) { 7146 const PetscInt newp = (c - cStart)*8; 7147 const PetscInt *cone, *ornt; 7148 PetscInt coneNew[6], orntNew[6]; 7149 7150 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7151 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7152 /* A hex */ 7153 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 7154 orntNew[0] = ornt[0]; 7155 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7156 orntNew[1] = 0; 7157 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 7158 orntNew[2] = ornt[2]; 7159 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7160 orntNew[3] = 0; 7161 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7162 orntNew[4] = 0; 7163 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 7164 orntNew[5] = ornt[5]; 7165 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 7166 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 7167 #if 1 7168 if ((newp+0 < cStartNew) || (newp+0 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+0, cStartNew, cMaxNew); 7169 for (p = 0; p < 6; ++p) { 7170 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 7171 } 7172 #endif 7173 /* B hex */ 7174 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 7175 orntNew[0] = ornt[0]; 7176 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7177 orntNew[1] = 0; 7178 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7179 orntNew[2] = -1; 7180 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 7181 orntNew[3] = ornt[3]; 7182 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7183 orntNew[4] = 0; 7184 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 7185 orntNew[5] = ornt[5]; 7186 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 7187 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 7188 #if 1 7189 if ((newp+1 < cStartNew) || (newp+1 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+1, cStartNew, cMaxNew); 7190 for (p = 0; p < 6; ++p) { 7191 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 7192 } 7193 #endif 7194 /* C hex */ 7195 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 7196 orntNew[0] = ornt[0]; 7197 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7198 orntNew[1] = 0; 7199 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7200 orntNew[2] = -1; 7201 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 7202 orntNew[3] = ornt[3]; 7203 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 7204 orntNew[4] = ornt[4]; 7205 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7206 orntNew[5] = -4; 7207 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 7208 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 7209 #if 1 7210 if ((newp+2 < cStartNew) || (newp+2 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+2, cStartNew, cMaxNew); 7211 for (p = 0; p < 6; ++p) { 7212 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 7213 } 7214 #endif 7215 /* D hex */ 7216 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 7217 orntNew[0] = ornt[0]; 7218 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7219 orntNew[1] = 0; 7220 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 7221 orntNew[2] = ornt[2]; 7222 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7223 orntNew[3] = 0; 7224 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 7225 orntNew[4] = ornt[4]; 7226 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7227 orntNew[5] = -4; 7228 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 7229 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 7230 #if 1 7231 if ((newp+3 < cStartNew) || (newp+3 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+3, cStartNew, cMaxNew); 7232 for (p = 0; p < 6; ++p) { 7233 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 7234 } 7235 #endif 7236 /* E hex */ 7237 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7238 orntNew[0] = -4; 7239 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 7240 orntNew[1] = ornt[1]; 7241 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 7242 orntNew[2] = ornt[2]; 7243 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7244 orntNew[3] = 0; 7245 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7246 orntNew[4] = -1; 7247 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 7248 orntNew[5] = ornt[5]; 7249 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 7250 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 7251 #if 1 7252 if ((newp+4 < cStartNew) || (newp+4 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+4, cStartNew, cMaxNew); 7253 for (p = 0; p < 6; ++p) { 7254 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 7255 } 7256 #endif 7257 /* F hex */ 7258 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7259 orntNew[0] = -4; 7260 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 7261 orntNew[1] = ornt[1]; 7262 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 7263 orntNew[2] = ornt[2]; 7264 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7265 orntNew[3] = -1; 7266 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 7267 orntNew[4] = ornt[4]; 7268 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7269 orntNew[5] = 1; 7270 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 7271 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 7272 #if 1 7273 if ((newp+5 < cStartNew) || (newp+5 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+5, cStartNew, cMaxNew); 7274 for (p = 0; p < 6; ++p) { 7275 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 7276 } 7277 #endif 7278 /* G hex */ 7279 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7280 orntNew[0] = -4; 7281 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 7282 orntNew[1] = ornt[1]; 7283 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7284 orntNew[2] = 0; 7285 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 7286 orntNew[3] = ornt[3]; 7287 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 7288 orntNew[4] = ornt[4]; 7289 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7290 orntNew[5] = -3; 7291 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 7292 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 7293 #if 1 7294 if ((newp+6 < cStartNew) || (newp+6 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+6, cStartNew, cMaxNew); 7295 for (p = 0; p < 6; ++p) { 7296 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 7297 } 7298 #endif 7299 /* H hex */ 7300 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7301 orntNew[0] = -4; 7302 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 7303 orntNew[1] = ornt[1]; 7304 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7305 orntNew[2] = -1; 7306 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 7307 orntNew[3] = ornt[3]; 7308 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7309 orntNew[4] = 3; 7310 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 7311 orntNew[5] = ornt[5]; 7312 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 7313 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 7314 #if 1 7315 if ((newp+7 < cStartNew) || (newp+7 >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", newp+7, cStartNew, cMaxNew); 7316 for (p = 0; p < 6; ++p) { 7317 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 7318 } 7319 #endif 7320 } 7321 /* Hybrid cells have 6 faces: Front, Back, Sides */ 7322 /* 7323 3---------2---------2 7324 | | | 7325 | D 2 C | 7326 | | | 7327 3----3----0----1----1 7328 | | | 7329 | A 0 B | 7330 | | | 7331 0---------0---------1 7332 */ 7333 for (c = cMax; c < cEnd; ++c) { 7334 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 7335 const PetscInt *cone, *ornt, *fornt; 7336 PetscInt coneNew[6], orntNew[6], o, of, i; 7337 7338 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7339 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7340 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 7341 o = ornt[0] < 0 ? -1 : 1; 7342 for (r = 0; r < 4; ++r) { 7343 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 7344 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 7345 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 7346 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]); 7347 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 7348 orntNew[0] = ornt[0]; 7349 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 7350 orntNew[1] = ornt[0]; 7351 of = fornt[edgeA] < 0 ? -1 : 1; 7352 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 7353 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 7354 orntNew[i] = ornt[edgeA]; 7355 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 7356 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 7357 orntNew[i] = 0; 7358 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 7359 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 7360 orntNew[i] = -2; 7361 of = fornt[edgeB] < 0 ? -1 : 1; 7362 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 7363 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 7364 orntNew[i] = ornt[edgeB]; 7365 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7366 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7367 #if 1 7368 if ((newp+r < cMaxNew) || (newp+r >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", newp+r, cMaxNew, cEndNew); 7369 for (p = 0; p < 2; ++p) { 7370 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", coneNew[p], fStartNew, fMaxNew); 7371 } 7372 for (p = 2; p < 6; ++p) { 7373 if ((coneNew[p] < fMaxNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", coneNew[p], fMaxNew, fEndNew); 7374 } 7375 #endif 7376 } 7377 } 7378 /* Interior split faces have 4 edges and the same cells as the parent */ 7379 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7380 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 7381 for (f = fStart; f < fMax; ++f) { 7382 for (r = 0; r < 4; ++r) { 7383 /* TODO: This can come from GetFaces_Internal() */ 7384 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}; 7385 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 7386 const PetscInt *cone, *ornt, *support; 7387 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 7388 7389 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7390 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7391 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 7392 orntNew[(r+3)%4] = ornt[(r+3)%4]; 7393 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 7394 orntNew[(r+0)%4] = ornt[r]; 7395 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7396 orntNew[(r+1)%4] = 0; 7397 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 7398 orntNew[(r+2)%4] = -2; 7399 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7400 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7401 #if 1 7402 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7403 for (p = 0; p < 4; ++p) { 7404 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7405 } 7406 #endif 7407 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7408 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7409 for (s = 0; s < supportSize; ++s) { 7410 PetscInt subf; 7411 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7412 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7413 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7414 for (c = 0; c < coneSize; ++c) { 7415 if (cone[c] == f) break; 7416 } 7417 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 7418 if (support[s] < cMax) { 7419 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 7420 } else { 7421 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 7422 } 7423 } 7424 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7425 #if 1 7426 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7427 for (p = 0; p < supportSize; ++p) { 7428 if ((supportRef[p] < cStartNew) || (supportRef[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportRef[p], cStartNew, cEndNew); 7429 } 7430 #endif 7431 } 7432 } 7433 /* Interior cell faces have 4 edges and 2 cells */ 7434 for (c = cStart; c < cMax; ++c) { 7435 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}; 7436 const PetscInt *cone, *ornt; 7437 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 7438 7439 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7440 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7441 /* A-D face */ 7442 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 7443 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 7444 orntNew[0] = 0; 7445 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7446 orntNew[1] = 0; 7447 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7448 orntNew[2] = -2; 7449 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 7450 orntNew[3] = -2; 7451 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7452 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7453 #if 1 7454 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7455 for (p = 0; p < 4; ++p) { 7456 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7457 } 7458 #endif 7459 /* C-D face */ 7460 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 7461 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 7462 orntNew[0] = 0; 7463 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7464 orntNew[1] = 0; 7465 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7466 orntNew[2] = -2; 7467 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 7468 orntNew[3] = -2; 7469 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7470 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7471 #if 1 7472 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7473 for (p = 0; p < 4; ++p) { 7474 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7475 } 7476 #endif 7477 /* B-C face */ 7478 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 7479 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 7480 orntNew[0] = -2; 7481 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 7482 orntNew[1] = 0; 7483 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7484 orntNew[2] = 0; 7485 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7486 orntNew[3] = -2; 7487 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7488 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7489 #if 1 7490 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7491 for (p = 0; p < 4; ++p) { 7492 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7493 } 7494 #endif 7495 /* A-B face */ 7496 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 7497 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 7498 orntNew[0] = -2; 7499 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 7500 orntNew[1] = 0; 7501 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7502 orntNew[2] = 0; 7503 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7504 orntNew[3] = -2; 7505 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7506 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7507 #if 1 7508 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7509 for (p = 0; p < 4; ++p) { 7510 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7511 } 7512 #endif 7513 /* E-F face */ 7514 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 7515 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7516 orntNew[0] = -2; 7517 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 7518 orntNew[1] = -2; 7519 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 7520 orntNew[2] = 0; 7521 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7522 orntNew[3] = 0; 7523 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7524 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7525 #if 1 7526 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7527 for (p = 0; p < 4; ++p) { 7528 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7529 } 7530 #endif 7531 /* F-G face */ 7532 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 7533 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7534 orntNew[0] = -2; 7535 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 7536 orntNew[1] = -2; 7537 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 7538 orntNew[2] = 0; 7539 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7540 orntNew[3] = 0; 7541 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7542 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7543 #if 1 7544 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7545 for (p = 0; p < 4; ++p) { 7546 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7547 } 7548 #endif 7549 /* G-H face */ 7550 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 7551 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 7552 orntNew[0] = -2; 7553 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 7554 orntNew[1] = 0; 7555 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7556 orntNew[2] = 0; 7557 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7558 orntNew[3] = -2; 7559 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7560 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7561 #if 1 7562 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7563 for (p = 0; p < 4; ++p) { 7564 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7565 } 7566 #endif 7567 /* E-H face */ 7568 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 7569 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7570 orntNew[0] = -2; 7571 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 7572 orntNew[1] = -2; 7573 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 7574 orntNew[2] = 0; 7575 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7576 orntNew[3] = 0; 7577 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7578 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7579 #if 1 7580 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7581 for (p = 0; p < 4; ++p) { 7582 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7583 } 7584 #endif 7585 /* A-E face */ 7586 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 7587 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 7588 orntNew[0] = 0; 7589 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7590 orntNew[1] = 0; 7591 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7592 orntNew[2] = -2; 7593 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 7594 orntNew[3] = -2; 7595 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7596 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7597 #if 1 7598 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7599 for (p = 0; p < 4; ++p) { 7600 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7601 } 7602 #endif 7603 /* D-F face */ 7604 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 7605 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7606 orntNew[0] = -2; 7607 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7608 orntNew[1] = 0; 7609 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7610 orntNew[2] = 0; 7611 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7612 orntNew[3] = -2; 7613 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7614 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7615 #if 1 7616 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7617 for (p = 0; p < 4; ++p) { 7618 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7619 } 7620 #endif 7621 /* C-G face */ 7622 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 7623 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7624 orntNew[0] = -2; 7625 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7626 orntNew[1] = -2; 7627 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7628 orntNew[2] = 0; 7629 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7630 orntNew[3] = 0; 7631 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7632 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7633 #if 1 7634 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7635 for (p = 0; p < 4; ++p) { 7636 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7637 } 7638 #endif 7639 /* B-H face */ 7640 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 7641 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7642 orntNew[0] = 0; 7643 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7644 orntNew[1] = -2; 7645 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7646 orntNew[2] = -2; 7647 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7648 orntNew[3] = 0; 7649 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7650 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7651 #if 1 7652 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7653 for (p = 0; p < 4; ++p) { 7654 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7655 } 7656 #endif 7657 for (r = 0; r < 12; ++r) { 7658 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 7659 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7660 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7661 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7662 #if 1 7663 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", newp, fStartNew, fMaxNew); 7664 for (p = 0; p < 2; ++p) { 7665 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a cell [%d, %d)", supportNew[p], cStartNew, cMaxNew); 7666 } 7667 #endif 7668 } 7669 } 7670 /* Hybrid split faces have 4 edges and same cells */ 7671 for (f = fMax; f < fEnd; ++f) { 7672 const PetscInt *cone, *ornt, *support; 7673 PetscInt coneNew[4], orntNew[4]; 7674 PetscInt supportNew[2], size, s, c; 7675 7676 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7677 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7678 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7679 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7680 for (r = 0; r < 2; ++r) { 7681 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 7682 7683 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 7684 orntNew[0] = ornt[0]; 7685 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 7686 orntNew[1] = ornt[1]; 7687 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 7688 orntNew[2+r] = 0; 7689 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7690 orntNew[3-r] = 0; 7691 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7692 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7693 #if 1 7694 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 7695 for (p = 0; p < 2; ++p) { 7696 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7697 } 7698 for (p = 2; p < 4; ++p) { 7699 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew); 7700 } 7701 #endif 7702 for (s = 0; s < size; ++s) { 7703 const PetscInt *coneCell, *orntCell, *fornt; 7704 PetscInt o, of; 7705 7706 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7707 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7708 o = orntCell[0] < 0 ? -1 : 1; 7709 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 7710 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %d in cone of cell %d", f, support[s]); 7711 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 7712 of = fornt[c-2] < 0 ? -1 : 1; 7713 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 7714 } 7715 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7716 #if 1 7717 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp, fMaxNew, fEndNew); 7718 for (p = 0; p < size; ++p) { 7719 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew); 7720 } 7721 #endif 7722 } 7723 } 7724 /* Hybrid cell faces have 4 edges and 2 cells */ 7725 for (c = cMax; c < cEnd; ++c) { 7726 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 7727 const PetscInt *cone, *ornt; 7728 PetscInt coneNew[4], orntNew[4]; 7729 PetscInt supportNew[2]; 7730 7731 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7732 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7733 for (r = 0; r < 4; ++r) { 7734 #if 0 7735 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 7736 orntNew[0] = 0; 7737 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 7738 orntNew[1] = 0; 7739 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 7740 orntNew[2] = 0; 7741 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7742 orntNew[3] = 0; 7743 #else 7744 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 7745 orntNew[0] = 0; 7746 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 7747 orntNew[1] = 0; 7748 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 7749 orntNew[2] = 0; 7750 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7751 orntNew[3] = 0; 7752 #endif 7753 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7754 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7755 #if 1 7756 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew); 7757 for (p = 0; p < 2; ++p) { 7758 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", coneNew[p], eStartNew, eMaxNew); 7759 } 7760 for (p = 2; p < 4; ++p) { 7761 if ((coneNew[p] < eMaxNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", coneNew[p], eMaxNew, eEndNew); 7762 } 7763 #endif 7764 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 7765 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 7766 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 7767 #if 1 7768 if ((newp+r < fMaxNew) || (newp+r >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", newp+r, fMaxNew, fEndNew); 7769 for (p = 0; p < 2; ++p) { 7770 if ((supportNew[p] < cMaxNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid cell [%d, %d)", supportNew[p], cMaxNew, cEndNew); 7771 } 7772 #endif 7773 } 7774 } 7775 /* Interior split edges have 2 vertices and the same faces as the parent */ 7776 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7777 for (e = eStart; e < eMax; ++e) { 7778 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7779 7780 for (r = 0; r < 2; ++r) { 7781 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7782 const PetscInt *cone, *ornt, *support; 7783 PetscInt coneNew[2], coneSize, c, supportSize, s; 7784 7785 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7786 coneNew[0] = vStartNew + (cone[0] - vStart); 7787 coneNew[1] = vStartNew + (cone[1] - vStart); 7788 coneNew[(r+1)%2] = newv; 7789 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7790 #if 1 7791 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 7792 for (p = 0; p < 2; ++p) { 7793 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 7794 } 7795 #endif 7796 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7797 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7798 for (s = 0; s < supportSize; ++s) { 7799 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7800 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7801 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7802 for (c = 0; c < coneSize; ++c) { 7803 if (cone[c] == e) break; 7804 } 7805 if (support[s] < fMax) { 7806 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 7807 } else { 7808 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 7809 } 7810 } 7811 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7812 #if 1 7813 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 7814 for (p = 0; p < supportSize; ++p) { 7815 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 7816 } 7817 #endif 7818 } 7819 } 7820 /* Interior face edges have 2 vertices and 2+cells faces */ 7821 for (f = fStart; f < fMax; ++f) { 7822 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}; 7823 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 7824 const PetscInt *cone, *coneCell, *orntCell, *support; 7825 PetscInt coneNew[2], coneSize, c, supportSize, s; 7826 7827 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7828 for (r = 0; r < 4; ++r) { 7829 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7830 7831 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7832 coneNew[1] = newv; 7833 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7834 #if 1 7835 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 7836 for (p = 0; p < 2; ++p) { 7837 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 7838 } 7839 #endif 7840 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7841 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7842 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7843 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7844 for (s = 0; s < supportSize; ++s) { 7845 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7846 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7847 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7848 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7849 if (support[s] < cMax) { 7850 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7851 } else { 7852 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 7853 } 7854 } 7855 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7856 #if 1 7857 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 7858 for (p = 0; p < 2+supportSize; ++p) { 7859 if ((supportRef[p] < fStartNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportRef[p], fStartNew, fEndNew); 7860 } 7861 #endif 7862 } 7863 } 7864 /* Interior cell edges have 2 vertices and 4 faces */ 7865 for (c = cStart; c < cMax; ++c) { 7866 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}; 7867 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 7868 const PetscInt *cone; 7869 PetscInt coneNew[2], supportNew[4]; 7870 7871 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7872 for (r = 0; r < 6; ++r) { 7873 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 7874 7875 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 7876 coneNew[1] = newv; 7877 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7878 #if 1 7879 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 7880 for (p = 0; p < 2; ++p) { 7881 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 7882 } 7883 #endif 7884 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7885 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7886 #if 1 7887 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", newp, eStartNew, eMaxNew); 7888 for (p = 0; p < 4; ++p) { 7889 if ((supportNew[p] < fStartNew) || (supportNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a face [%d, %d)", supportNew[p], fStartNew, fMaxNew); 7890 } 7891 #endif 7892 } 7893 } 7894 /* Hybrid edges have two vertices and the same faces */ 7895 for (e = eMax; e < eEnd; ++e) { 7896 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 7897 const PetscInt *cone, *support, *fcone; 7898 PetscInt coneNew[2], size, fsize, s; 7899 7900 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7901 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7902 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7903 coneNew[0] = vStartNew + (cone[0] - vStart); 7904 coneNew[1] = vStartNew + (cone[1] - vStart); 7905 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7906 #if 1 7907 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 7908 for (p = 0; p < 2; ++p) { 7909 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 7910 } 7911 #endif 7912 for (s = 0; s < size; ++s) { 7913 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 7914 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 7915 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 7916 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %d not found in cone of face %d", e, support[s]); 7917 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 7918 } 7919 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7920 #if 1 7921 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 7922 for (p = 0; p < size; ++p) { 7923 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew); 7924 } 7925 #endif 7926 } 7927 /* Hybrid face edges have 2 vertices and 2+cells faces */ 7928 for (f = fMax; f < fEnd; ++f) { 7929 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7930 const PetscInt *cone, *support, *ccone, *cornt; 7931 PetscInt coneNew[2], size, csize, s; 7932 7933 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7934 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7935 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7936 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 7937 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 7938 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7939 #if 1 7940 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 7941 for (p = 0; p < 2; ++p) { 7942 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 7943 } 7944 #endif 7945 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 7946 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 7947 for (s = 0; s < size; ++s) { 7948 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 7949 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 7950 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 7951 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 7952 if ((c < 2) || (c >= csize)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Hybrid face %d is not in cone of hybrid cell %d", f, support[s]); 7953 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 7954 } 7955 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7956 #if 1 7957 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 7958 for (p = 0; p < 2+size; ++p) { 7959 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew); 7960 } 7961 #endif 7962 } 7963 /* Hybrid cell edges have 2 vertices and 4 faces */ 7964 for (c = cMax; c < cEnd; ++c) { 7965 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7966 const PetscInt *cone, *support; 7967 PetscInt coneNew[2], size; 7968 7969 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7970 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 7971 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 7972 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 7973 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 7974 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7975 #if 1 7976 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 7977 for (p = 0; p < 2; ++p) { 7978 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", coneNew[p], vStartNew, vEndNew); 7979 } 7980 #endif 7981 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 7982 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 7983 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 7984 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 7985 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7986 #if 1 7987 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid edge [%d, %d)", newp, eMaxNew, eEndNew); 7988 for (p = 0; p < 4; ++p) { 7989 if ((supportRef[p] < fMaxNew) || (supportRef[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a hybrid face [%d, %d)", supportRef[p], fMaxNew, fEndNew); 7990 } 7991 #endif 7992 } 7993 /* Interior vertices have identical supports */ 7994 for (v = vStart; v < vEnd; ++v) { 7995 const PetscInt newp = vStartNew + (v - vStart); 7996 const PetscInt *support, *cone; 7997 PetscInt size, s; 7998 7999 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 8000 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 8001 for (s = 0; s < size; ++s) { 8002 PetscInt r = 0; 8003 8004 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8005 if (cone[1] == v) r = 1; 8006 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 8007 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 8008 } 8009 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8010 #if 1 8011 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 8012 for (p = 0; p < size; ++p) { 8013 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 8014 } 8015 #endif 8016 } 8017 /* Interior edge vertices have 2 + faces supports */ 8018 for (e = eStart; e < eMax; ++e) { 8019 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 8020 const PetscInt *cone, *support; 8021 PetscInt size, s; 8022 8023 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8024 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8025 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 8026 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 8027 for (s = 0; s < size; ++s) { 8028 PetscInt r; 8029 8030 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8031 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 8032 if (support[s] < fMax) { 8033 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 8034 } else { 8035 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 8036 } 8037 } 8038 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8039 #if 1 8040 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 8041 for (p = 0; p < 2+size; ++p) { 8042 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 8043 } 8044 #endif 8045 } 8046 /* Interior face vertices have 4 + cells supports */ 8047 for (f = fStart; f < fMax; ++f) { 8048 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8049 const PetscInt *cone, *support; 8050 PetscInt size, s; 8051 8052 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8053 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8054 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 8055 for (s = 0; s < size; ++s) { 8056 PetscInt r; 8057 8058 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8059 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 8060 if (support[s] < cMax) { 8061 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 8062 } else { 8063 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 8064 } 8065 } 8066 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8067 #if 1 8068 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not a vertex [%d, %d)", newp, vStartNew, vEndNew); 8069 for (p = 0; p < 4+size; ++p) { 8070 if ((supportRef[p] < eStartNew) || (supportRef[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %d is not an edge [%d, %d)", supportRef[p], eStartNew, eEndNew); 8071 } 8072 #endif 8073 } 8074 /* Cell vertices have 6 supports */ 8075 for (c = cStart; c < cMax; ++c) { 8076 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 8077 PetscInt supportNew[6]; 8078 8079 for (r = 0; r < 6; ++r) { 8080 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8081 } 8082 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8083 } 8084 ierr = PetscFree(supportRef);CHKERRQ(ierr); 8085 break; 8086 default: 8087 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 8088 } 8089 PetscFunctionReturn(0); 8090 } 8091 8092 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8093 { 8094 PetscSection coordSection, coordSectionNew; 8095 Vec coordinates, coordinatesNew; 8096 PetscScalar *coords, *coordsNew; 8097 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 8098 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 8099 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 8100 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 8101 VecType vtype; 8102 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 8103 const PetscReal *maxCell, *L; 8104 const DMBoundaryType *bd; 8105 PetscErrorCode ierr; 8106 8107 PetscFunctionBegin; 8108 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8109 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8110 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8111 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8112 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8113 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8114 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 8115 if (cMax < 0) cMax = cEnd; 8116 if (fMax < 0) fMax = fEnd; 8117 if (eMax < 0) eMax = eEnd; 8118 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 8119 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 8120 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 8121 /* Determine if we need to localize coordinates when generating them */ 8122 if (isperiodic && !maxCell) { 8123 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 8124 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 8125 } 8126 if (isperiodic) { 8127 ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr); 8128 ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr); 8129 ierr = PetscOptionsEnd();CHKERRQ(ierr); 8130 if (localize) { 8131 ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 8132 } 8133 } 8134 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 8135 8136 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 8137 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 8138 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 8139 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 8140 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 8141 8142 if (localize) { 8143 PetscInt p, r, newp, *pi; 8144 8145 /* New coordinates will be already localized on the cell */ 8146 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 8147 8148 /* We need the parentId to properly localize coordinates */ 8149 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 8150 switch (refiner) { 8151 case REFINER_NOOP: 8152 break; 8153 case REFINER_SIMPLEX_1D: 8154 for (p = cStart; p < cEnd; ++p) { 8155 for (r = 0; r < 2; ++r) { 8156 newp = (p - cStart)*2 + r; 8157 pi[newp] = p; 8158 } 8159 } 8160 break; 8161 case REFINER_SIMPLEX_2D: 8162 for (p = cStart; p < cEnd; ++p) { 8163 for (r = 0; r < 4; ++r) { 8164 newp = (p - cStart)*4 + r; 8165 pi[newp] = p; 8166 } 8167 } 8168 break; 8169 case REFINER_HEX_2D: 8170 for (p = cStart; p < cEnd; ++p) { 8171 for (r = 0; r < 4; ++r) { 8172 newp = (p - cStart)*4 + r; 8173 pi[newp] = p; 8174 } 8175 } 8176 break; 8177 case REFINER_SIMPLEX_TO_HEX_2D: 8178 for (p = cStart; p < cEnd; ++p) { 8179 for (r = 0; r < 3; ++r) { 8180 newp = (p - cStart)*3 + r; 8181 pi[newp] = p; 8182 } 8183 } 8184 break; 8185 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8186 for (p = cStart; p < cMax; ++p) { 8187 for (r = 0; r < 3; ++r) { 8188 newp = (p - cStart)*3 + r; 8189 pi[newp] = p; 8190 } 8191 } 8192 for (p = cMax; p < cEnd; ++p) { 8193 for (r = 0; r < 4; ++r) { 8194 newp = (cMax - cStart)*3 + (p - cMax)*4 + r; 8195 pi[newp] = p; 8196 } 8197 } 8198 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8199 cMax = cEnd; 8200 eMax = eEnd; 8201 break; 8202 case REFINER_HYBRID_SIMPLEX_2D: 8203 for (p = cStart; p < cMax; ++p) { 8204 for (r = 0; r < 4; ++r) { 8205 newp = (p - cStart)*4 + r; 8206 pi[newp] = p; 8207 } 8208 } 8209 for (p = cMax; p < cEnd; ++p) { 8210 for (r = 0; r < 2; ++r) { 8211 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8212 pi[newp] = p; 8213 } 8214 } 8215 break; 8216 case REFINER_HYBRID_HEX_2D: 8217 for (p = cStart; p < cMax; ++p) { 8218 for (r = 0; r < 4; ++r) { 8219 newp = (p - cStart)*4 + r; 8220 pi[newp] = p; 8221 } 8222 } 8223 for (p = cMax; p < cEnd; ++p) { 8224 for (r = 0; r < 2; ++r) { 8225 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8226 pi[newp] = p; 8227 } 8228 } 8229 break; 8230 case REFINER_SIMPLEX_3D: 8231 for (p = cStart; p < cEnd; ++p) { 8232 for (r = 0; r < 8; ++r) { 8233 newp = (p - cStart)*8 + r; 8234 pi[newp] = p; 8235 } 8236 } 8237 break; 8238 case REFINER_HYBRID_SIMPLEX_3D: 8239 for (p = cStart; p < cMax; ++p) { 8240 for (r = 0; r < 8; ++r) { 8241 newp = (p - cStart)*8 + r; 8242 pi[newp] = p; 8243 } 8244 } 8245 for (p = cMax; p < cEnd; ++p) { 8246 for (r = 0; r < 4; ++r) { 8247 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8248 pi[newp] = p; 8249 } 8250 } 8251 break; 8252 case REFINER_SIMPLEX_TO_HEX_3D: 8253 for (p = cStart; p < cEnd; ++p) { 8254 for (r = 0; r < 4; ++r) { 8255 newp = (p - cStart)*4 + r; 8256 pi[newp] = p; 8257 } 8258 } 8259 break; 8260 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8261 for (p = cStart; p < cMax; ++p) { 8262 for (r = 0; r < 4; ++r) { 8263 newp = (p - cStart)*4 + r; 8264 pi[newp] = p; 8265 } 8266 } 8267 for (p = cMax; p < cEnd; ++p) { 8268 for (r = 0; r < 3; ++r) { 8269 newp = (cMax - cStart)*4 + (p - cMax)*3 + r; 8270 pi[newp] = p; 8271 } 8272 } 8273 break; 8274 case REFINER_HEX_3D: 8275 for (p = cStart; p < cEnd; ++p) { 8276 for (r = 0; r < 8; ++r) { 8277 newp = (p - cStart)*8 + r; 8278 pi[newp] = p; 8279 } 8280 } 8281 break; 8282 case REFINER_HYBRID_HEX_3D: 8283 for (p = cStart; p < cMax; ++p) { 8284 for (r = 0; r < 8; ++r) { 8285 newp = (p - cStart)*8 + r; 8286 pi[newp] = p; 8287 } 8288 } 8289 for (p = cMax; p < cEnd; ++p) { 8290 for (r = 0; r < 4; ++r) { 8291 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8292 pi[newp] = p; 8293 } 8294 } 8295 break; 8296 default: 8297 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 8298 } 8299 parentId = pi; 8300 } else { 8301 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8302 if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; } 8303 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 8304 } 8305 8306 /* All vertices have the spaceDim coordinates */ 8307 if (localize) { 8308 PetscInt c; 8309 8310 for (c = cStartNew; c < cEndNew; ++c) { 8311 PetscInt *cone = NULL; 8312 PetscInt closureSize, coneSize = 0, p, pdof; 8313 8314 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 8315 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 8316 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8317 for (p = 0; p < closureSize*2; p += 2) { 8318 const PetscInt point = cone[p]; 8319 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 8320 } 8321 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8322 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 8323 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 8324 } 8325 } 8326 } 8327 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 8328 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 8329 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 8330 } 8331 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 8332 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 8333 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8334 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 8335 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 8336 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 8337 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 8338 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 8339 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 8340 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 8341 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 8342 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 8343 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8344 8345 switch (refiner) { 8346 case REFINER_NOOP: break; 8347 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8348 case REFINER_SIMPLEX_TO_HEX_3D: 8349 case REFINER_HEX_3D: 8350 case REFINER_HYBRID_HEX_3D: 8351 /* Face vertices have the average of corner coordinates */ 8352 for (f = fStart; f < fMax; ++f) { 8353 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8354 PetscInt *cone = NULL; 8355 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 8356 8357 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8358 for (p = 0; p < closureSize*2; p += 2) { 8359 const PetscInt point = cone[p]; 8360 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8361 } 8362 if (localize) { 8363 const PetscInt *support = NULL; 8364 PetscInt *rStar = NULL; 8365 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 8366 PetscBool cellfound = PETSC_FALSE; 8367 8368 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8369 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 8370 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 8371 /* Compute average of coordinates for each cell sharing the face */ 8372 for (s = 0; s < supportSize; ++s) { 8373 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 8374 PetscInt *cellCone = NULL; 8375 PetscInt cellClosureSize, cellConeSize = 0, cdof; 8376 const PetscInt cell = support[s]; 8377 PetscBool copyoff = PETSC_FALSE; 8378 8379 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8380 for (p = 0; p < cellClosureSize*2; p += 2) { 8381 const PetscInt point = cellCone[p]; 8382 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 8383 } 8384 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8385 if (!cdof) { /* the parent cell does not have localized coordinates */ 8386 cellfound = PETSC_TRUE; 8387 for (v = 0; v < coneSize; ++v) { 8388 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8389 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 8390 } 8391 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8392 } else { 8393 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8394 for (p = 0; p < coneSize; ++p) { 8395 const PetscInt tv = cone[p]; 8396 PetscInt cv, voff; 8397 PetscBool locv = PETSC_TRUE; 8398 8399 for (cv = 0; cv < cellConeSize; ++cv) { 8400 if (cellCone[cv] == tv) { 8401 ccoff[p] = spaceDim*cv + coff; 8402 break; 8403 } 8404 } 8405 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D\n",tv); 8406 8407 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 8408 for (d = 0; d < spaceDim; ++d) { 8409 coordsNewAux[d] += coords[ccoff[p]+d]; 8410 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 8411 } 8412 if (locv && !cellfound) { 8413 cellfound = PETSC_TRUE; 8414 copyoff = PETSC_TRUE; 8415 } 8416 } 8417 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8418 8419 /* Found a valid face for the "vertex" part of the Section (physical space) 8420 i.e., a face that has at least one corner in the physical space */ 8421 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 8422 } 8423 8424 /* Localize new coordinates on each refined cell */ 8425 for (v = 0; v < rStarSize*2; v += 2) { 8426 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 8427 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 8428 const PetscInt rcell = rStar[v]; 8429 8430 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8431 if (!rcdof) continue; 8432 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 8433 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8434 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8435 if (rcone[p] == newv) { 8436 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 8437 break; 8438 } 8439 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8440 } 8441 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8442 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 8443 } 8444 } 8445 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8446 } 8447 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8448 if (!cellfound) { 8449 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 8450 needcoords = PETSC_TRUE; 8451 coneSize = 0; 8452 } 8453 } else { 8454 for (v = 0; v < coneSize; ++v) { 8455 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8456 } 8457 } 8458 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8459 if (coneSize) { 8460 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8461 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8462 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8463 } else { 8464 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8465 } 8466 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8467 } 8468 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8469 case REFINER_SIMPLEX_TO_HEX_2D: 8470 case REFINER_HEX_2D: 8471 case REFINER_HYBRID_HEX_2D: 8472 case REFINER_SIMPLEX_1D: 8473 /* Cell vertices have the average of corner coordinates */ 8474 for (c = cStart; c < cMax; ++c) { 8475 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 8476 PetscInt *cone = NULL; 8477 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 8478 8479 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8480 for (p = 0; p < closureSize*2; p += 2) { 8481 const PetscInt point = cone[p]; 8482 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8483 } 8484 if (localize) { 8485 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 8486 } 8487 if (cdof) { 8488 PetscInt coff; 8489 8490 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 8491 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 8492 } else { 8493 for (v = 0; v < coneSize; ++v) { 8494 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8495 } 8496 } 8497 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8498 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8499 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8500 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8501 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8502 8503 /* Localize new coordinates on each refined cell */ 8504 if (cdof) { 8505 PetscInt *rStar = NULL, rStarSize; 8506 8507 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8508 for (v = 0; v < rStarSize*2; v += 2) { 8509 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 8510 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 8511 8512 rc = rStar[v]; 8513 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 8514 if (!rcdof) continue; 8515 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 8516 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8517 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 8518 if (cone[p] == newv) { 8519 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 8520 break; 8521 } 8522 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 8523 } 8524 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 8525 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8526 } 8527 } 8528 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8529 } 8530 } 8531 case REFINER_SIMPLEX_2D: 8532 case REFINER_HYBRID_SIMPLEX_2D: 8533 case REFINER_SIMPLEX_3D: 8534 case REFINER_HYBRID_SIMPLEX_3D: 8535 /* Edge vertices have the average of endpoint coordinates */ 8536 for (e = eStart; e < eMax; ++e) { 8537 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 8538 const PetscInt *cone; 8539 PetscInt coneSize, offA, offB, offnew, d; 8540 8541 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 8542 if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %d cone should have two vertices, not %d", e, coneSize); 8543 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8544 if (localize) { 8545 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 8546 PetscInt *eStar = NULL, eStarSize; 8547 PetscInt *rStar = NULL, rStarSize; 8548 PetscBool cellfound = PETSC_FALSE; 8549 8550 offA = offB = -1; 8551 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 8552 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 8553 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8554 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8555 for (v = 0; v < eStarSize*2; v += 2) { 8556 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 8557 PetscScalar coordsNewAux[3]; 8558 PetscInt *cellCone = NULL; 8559 PetscInt cellClosureSize, s, cv, cdof; 8560 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 8561 const PetscInt cell = eStar[v]; 8562 8563 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8564 if (!cdof) { 8565 /* Found a valid edge for the "vertex" part of the Section */ 8566 offA = voffA; 8567 offB = voffB; 8568 cellfound = PETSC_TRUE; 8569 } else { 8570 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8571 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8572 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 8573 const PetscInt point = cellCone[s]; 8574 if ((point >= vStart) && (point < vEnd)) { 8575 if (point == cone[0]) toffA = spaceDim*cv + coff; 8576 else if (point == cone[1]) toffB = spaceDim*cv + coff; 8577 cv++; 8578 } 8579 } 8580 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8581 for (d = 0; d < spaceDim; ++d) { 8582 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 8583 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 8584 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 8585 } 8586 /* Found a valid edge for the "vertex" part of the Section */ 8587 if (!cellfound && (locvA || locvB)) { 8588 cellfound = PETSC_TRUE; 8589 offA = toffA; 8590 offB = toffB; 8591 } 8592 } 8593 8594 /* Localize new coordinates on each refined cell */ 8595 for (s = 0; s < rStarSize*2; s += 2) { 8596 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 8597 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 8598 const PetscInt rcell = rStar[s]; 8599 8600 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8601 if (!rcdof) continue; 8602 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 8603 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8604 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8605 if (rcone[p] == newv) { 8606 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 8607 break; 8608 } 8609 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8610 } 8611 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8612 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 8613 } 8614 } 8615 } 8616 } 8617 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8618 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8619 if (!cellfound) { 8620 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 8621 needcoords = PETSC_TRUE; 8622 } 8623 } else { 8624 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 8625 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 8626 } 8627 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8628 if (offA != -1 && offB != -1) { 8629 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 8630 for (d = 0; d < spaceDim; ++d) { 8631 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 8632 } 8633 } else { 8634 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8635 } 8636 } 8637 /* Old vertices have the same coordinates */ 8638 for (v = vStart; v < vEnd; ++v) { 8639 const PetscInt newv = vStartNew + (v - vStart); 8640 PetscInt off, offnew, d; 8641 8642 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 8643 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8644 for (d = 0; d < spaceDim; ++d) { 8645 coordsNew[offnew+d] = coords[off+d]; 8646 } 8647 8648 /* Localize new coordinates on each refined cell */ 8649 if (localize) { 8650 PetscInt p; 8651 PetscInt *rStar = NULL, rStarSize; 8652 8653 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8654 for (p = 0; p < rStarSize*2; p += 2) { 8655 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 8656 PetscScalar ocoords[3]; 8657 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 8658 8659 c = rStar[p]; 8660 oc = parentId[c-cStartNew]; 8661 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 8662 if (!cdof) continue; 8663 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 8664 if (!cdof) continue; 8665 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 8666 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8667 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8668 if (cone[s] == v) { 8669 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 8670 break; 8671 } 8672 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 8673 } 8674 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D\n",v); 8675 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8676 8677 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 8678 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8679 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8680 if (cone[s] == newv) { 8681 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 8682 break; 8683 } 8684 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 8685 } 8686 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D\n",newv); 8687 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8688 } 8689 } 8690 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8691 } 8692 } 8693 break; 8694 default: 8695 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 8696 } 8697 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 8698 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8699 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 8700 8701 /* Final reduction (if needed) if we are localizing */ 8702 if (localize) { 8703 PetscBool gred; 8704 8705 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 8706 if (gred) { 8707 DM cdm; 8708 Vec aux; 8709 PetscSF sf; 8710 const PetscScalar *lArray; 8711 PetscScalar *gArray; 8712 8713 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 8714 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 8715 ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr); 8716 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8717 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 8718 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 8719 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8720 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8721 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8722 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 8723 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8724 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8725 ierr = VecDestroy(&aux);CHKERRQ(ierr); 8726 } 8727 } 8728 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 8729 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 8730 ierr = PetscFree(parentId);CHKERRQ(ierr); 8731 PetscFunctionReturn(0); 8732 } 8733 8734 /*@ 8735 DMPlexCreateProcessSF - Create an SF which just has process connectivity 8736 8737 Collective on DM 8738 8739 Input Parameters: 8740 + dm - The DM 8741 - sfPoint - The PetscSF which encodes point connectivity 8742 8743 Output Parameters: 8744 + processRanks - A list of process neighbors, or NULL 8745 - sfProcess - An SF encoding the process connectivity, or NULL 8746 8747 Level: developer 8748 8749 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 8750 @*/ 8751 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 8752 { 8753 PetscInt numRoots, numLeaves, l; 8754 const PetscInt *localPoints; 8755 const PetscSFNode *remotePoints; 8756 PetscInt *localPointsNew; 8757 PetscSFNode *remotePointsNew; 8758 PetscInt *ranks, *ranksNew; 8759 PetscMPIInt size; 8760 PetscErrorCode ierr; 8761 8762 PetscFunctionBegin; 8763 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8764 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 8765 if (processRanks) {PetscValidPointer(processRanks, 3);} 8766 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 8767 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 8768 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8769 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 8770 for (l = 0; l < numLeaves; ++l) { 8771 ranks[l] = remotePoints[l].rank; 8772 } 8773 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 8774 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 8775 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 8776 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 8777 for (l = 0; l < numLeaves; ++l) { 8778 ranksNew[l] = ranks[l]; 8779 localPointsNew[l] = l; 8780 remotePointsNew[l].index = 0; 8781 remotePointsNew[l].rank = ranksNew[l]; 8782 } 8783 ierr = PetscFree(ranks);CHKERRQ(ierr); 8784 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 8785 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 8786 if (sfProcess) { 8787 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 8788 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 8789 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 8790 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 8791 } 8792 PetscFunctionReturn(0); 8793 } 8794 8795 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8796 { 8797 PetscSF sf, sfNew, sfProcess; 8798 IS processRanks; 8799 MPI_Datatype depthType; 8800 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 8801 const PetscInt *localPoints, *neighbors; 8802 const PetscSFNode *remotePoints; 8803 PetscInt *localPointsNew; 8804 PetscSFNode *remotePointsNew; 8805 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 8806 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 8807 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8808 PetscErrorCode ierr; 8809 8810 PetscFunctionBegin; 8811 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 8812 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 8813 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 8814 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %d != %d", ldepth, depth); 8815 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8816 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8817 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8818 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8819 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 8820 cMax = cMax < 0 ? cEnd : cMax; 8821 fMax = fMax < 0 ? fEnd : fMax; 8822 eMax = eMax < 0 ? eEnd : eMax; 8823 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8824 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 8825 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 8826 /* Calculate size of new SF */ 8827 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8828 if (numRoots < 0) PetscFunctionReturn(0); 8829 for (l = 0; l < numLeaves; ++l) { 8830 const PetscInt p = localPoints[l]; 8831 8832 switch (refiner) { 8833 case REFINER_SIMPLEX_1D: 8834 if ((p >= vStart) && (p < vEnd)) { 8835 /* Interior vertices stay the same */ 8836 ++numLeavesNew; 8837 } else if ((p >= cStart && p < cMax)) { 8838 /* Interior cells add new cells and interior vertices */ 8839 numLeavesNew += 2 + 1; 8840 } 8841 break; 8842 case REFINER_SIMPLEX_2D: 8843 case REFINER_HYBRID_SIMPLEX_2D: 8844 if ((p >= vStart) && (p < vEnd)) { 8845 /* Interior vertices stay the same */ 8846 ++numLeavesNew; 8847 } else if ((p >= fStart) && (p < fMax)) { 8848 /* Interior faces add new faces and vertex */ 8849 numLeavesNew += 2 + 1; 8850 } else if ((p >= fMax) && (p < fEnd)) { 8851 /* Hybrid faces stay the same */ 8852 ++numLeavesNew; 8853 } else if ((p >= cStart) && (p < cMax)) { 8854 /* Interior cells add new cells and interior faces */ 8855 numLeavesNew += 4 + 3; 8856 } else if ((p >= cMax) && (p < cEnd)) { 8857 /* Hybrid cells add new cells and hybrid face */ 8858 numLeavesNew += 2 + 1; 8859 } 8860 break; 8861 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8862 case REFINER_SIMPLEX_TO_HEX_2D: 8863 if ((p >= vStart) && (p < vEnd)) { 8864 /* Interior vertices stay the same */ 8865 ++numLeavesNew; 8866 } else if ((p >= fStart) && (p < fEnd)) { 8867 /* Interior faces add new faces and vertex */ 8868 numLeavesNew += 2 + 1; 8869 } else if ((p >= cStart) && (p < cMax)) { 8870 /* Interior cells add new cells, interior faces, and vertex */ 8871 numLeavesNew += 3 + 3 + 1; 8872 } else if ((p >= cMax) && (p < cEnd)) { 8873 /* Hybrid cells add new cells, interior faces, and vertex */ 8874 numLeavesNew += 4 + 4 + 1; 8875 } 8876 break; 8877 case REFINER_HEX_2D: 8878 case REFINER_HYBRID_HEX_2D: 8879 if ((p >= vStart) && (p < vEnd)) { 8880 /* Interior vertices stay the same */ 8881 ++numLeavesNew; 8882 } else if ((p >= fStart) && (p < fMax)) { 8883 /* Interior faces add new faces and vertex */ 8884 numLeavesNew += 2 + 1; 8885 } else if ((p >= fMax) && (p < fEnd)) { 8886 /* Hybrid faces stay the same */ 8887 ++numLeavesNew; 8888 } else if ((p >= cStart) && (p < cMax)) { 8889 /* Interior cells add new cells, interior faces, and vertex */ 8890 numLeavesNew += 4 + 4 + 1; 8891 } else if ((p >= cMax) && (p < cEnd)) { 8892 /* Hybrid cells add new cells and hybrid face */ 8893 numLeavesNew += 2 + 1; 8894 } 8895 break; 8896 case REFINER_SIMPLEX_3D: 8897 case REFINER_HYBRID_SIMPLEX_3D: 8898 if ((p >= vStart) && (p < vEnd)) { 8899 /* Interior vertices stay the same */ 8900 ++numLeavesNew; 8901 } else if ((p >= eStart) && (p < eMax)) { 8902 /* Interior edges add new edges and vertex */ 8903 numLeavesNew += 2 + 1; 8904 } else if ((p >= eMax) && (p < eEnd)) { 8905 /* Hybrid edges stay the same */ 8906 ++numLeavesNew; 8907 } else if ((p >= fStart) && (p < fMax)) { 8908 /* Interior faces add new faces and edges */ 8909 numLeavesNew += 4 + 3; 8910 } else if ((p >= fMax) && (p < fEnd)) { 8911 /* Hybrid faces add new faces and edges */ 8912 numLeavesNew += 2 + 1; 8913 } else if ((p >= cStart) && (p < cMax)) { 8914 /* Interior cells add new cells, faces, and edges */ 8915 numLeavesNew += 8 + 8 + 1; 8916 } else if ((p >= cMax) && (p < cEnd)) { 8917 /* Hybrid cells add new cells and faces */ 8918 numLeavesNew += 4 + 3; 8919 } 8920 break; 8921 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8922 case REFINER_SIMPLEX_TO_HEX_3D: 8923 if ((p >= vStart) && (p < vEnd)) { 8924 /* Interior vertices stay the same */ 8925 ++numLeavesNew; 8926 } else if ((p >= eStart) && (p < eMax)) { 8927 /* Interior edges add new edges and vertex */ 8928 numLeavesNew += 2 + 1; 8929 } else if ((p >= eMax) && (p < eEnd)) { 8930 /* Hybrid edges stay the same */ 8931 ++numLeavesNew; 8932 } else if ((p >= fStart) && (p < fMax)) { 8933 /* Interior faces add new faces, edges and a vertex */ 8934 numLeavesNew += 3 + 3 + 1; 8935 } else if ((p >= fMax) && (p < fEnd)) { 8936 /* Hybrid faces add new faces and an edge */ 8937 numLeavesNew += 2 + 1; 8938 } else if ((p >= cStart) && (p < cMax)) { 8939 /* Interior cells add new cells, faces, edges and a vertex */ 8940 numLeavesNew += 4 + 6 + 4 + 1; 8941 } else if ((p >= cMax) && (p < cEnd)) { 8942 /* Hybrid cells add new cells, faces and an edge */ 8943 numLeavesNew += 3 + 3 + 1; 8944 } 8945 break; 8946 case REFINER_HEX_3D: 8947 case REFINER_HYBRID_HEX_3D: 8948 if ((p >= vStart) && (p < vEnd)) { 8949 /* Old vertices stay the same */ 8950 ++numLeavesNew; 8951 } else if ((p >= eStart) && (p < eMax)) { 8952 /* Interior edges add new edges, and vertex */ 8953 numLeavesNew += 2 + 1; 8954 } else if ((p >= eMax) && (p < eEnd)) { 8955 /* Hybrid edges stay the same */ 8956 ++numLeavesNew; 8957 } else if ((p >= fStart) && (p < fMax)) { 8958 /* Interior faces add new faces, edges, and vertex */ 8959 numLeavesNew += 4 + 4 + 1; 8960 } else if ((p >= fMax) && (p < fEnd)) { 8961 /* Hybrid faces add new faces and edges */ 8962 numLeavesNew += 2 + 1; 8963 } else if ((p >= cStart) && (p < cMax)) { 8964 /* Interior cells add new cells, faces, edges, and vertex */ 8965 numLeavesNew += 8 + 12 + 6 + 1; 8966 } else if ((p >= cStart) && (p < cEnd)) { 8967 /* Hybrid cells add new cells, faces, and edges */ 8968 numLeavesNew += 4 + 4 + 1; 8969 } 8970 break; 8971 default: 8972 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 8973 } 8974 } 8975 /* Communicate depthSizes for each remote rank */ 8976 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 8977 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 8978 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 8979 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 8980 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 8981 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 8982 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 8983 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 8984 for (n = 0; n < numNeighbors; ++n) { 8985 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 8986 } 8987 depthSizeOld[depth] = cMax; 8988 depthSizeOld[0] = vMax; 8989 depthSizeOld[depth-1] = fMax; 8990 depthSizeOld[1] = eMax; 8991 8992 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 8993 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 8994 8995 depthSizeOld[depth] = cEnd - cStart; 8996 depthSizeOld[0] = vEnd - vStart; 8997 depthSizeOld[depth-1] = fEnd - fStart; 8998 depthSizeOld[1] = eEnd - eStart; 8999 9000 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9001 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9002 for (n = 0; n < numNeighbors; ++n) { 9003 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 9004 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 9005 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]; 9006 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 9007 } 9008 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 9009 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 9010 /* Calculate new point SF */ 9011 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 9012 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 9013 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 9014 for (l = 0, m = 0; l < numLeaves; ++l) { 9015 PetscInt p = localPoints[l]; 9016 PetscInt rp = remotePoints[l].index, n; 9017 PetscMPIInt rrank = remotePoints[l].rank; 9018 9019 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 9020 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %d", rrank); 9021 switch (refiner) { 9022 case REFINER_SIMPLEX_1D: 9023 if ((p >= vStart) && (p < vEnd)) { 9024 /* Old vertices stay the same */ 9025 localPointsNew[m] = vStartNew + (p - vStart); 9026 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9027 remotePointsNew[m].rank = rrank; 9028 ++m; 9029 } else if ((p >= cStart) && (p < cMax)) { 9030 /* Old interior cells add new cells and vertex */ 9031 for (r = 0; r < 2; ++r, ++m) { 9032 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 9033 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 9034 remotePointsNew[m].rank = rrank; 9035 } 9036 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 9037 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 9038 remotePointsNew[m].rank = rrank; 9039 ++m; 9040 } 9041 break; 9042 case REFINER_SIMPLEX_2D: 9043 case REFINER_HYBRID_SIMPLEX_2D: 9044 if ((p >= vStart) && (p < vEnd)) { 9045 /* Old vertices stay the same */ 9046 localPointsNew[m] = vStartNew + (p - vStart); 9047 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9048 remotePointsNew[m].rank = rrank; 9049 ++m; 9050 } else if ((p >= fStart) && (p < fMax)) { 9051 /* Old interior faces add new faces and vertex */ 9052 for (r = 0; r < 2; ++r, ++m) { 9053 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9054 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9055 remotePointsNew[m].rank = rrank; 9056 } 9057 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9058 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9059 remotePointsNew[m].rank = rrank; 9060 ++m; 9061 } else if ((p >= fMax) && (p < fEnd)) { 9062 /* Old hybrid faces stay the same */ 9063 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9064 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9065 remotePointsNew[m].rank = rrank; 9066 ++m; 9067 } else if ((p >= cStart) && (p < cMax)) { 9068 /* Old interior cells add new cells and interior faces */ 9069 for (r = 0; r < 4; ++r, ++m) { 9070 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9071 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9072 remotePointsNew[m].rank = rrank; 9073 } 9074 for (r = 0; r < 3; ++r, ++m) { 9075 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 9076 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 9077 remotePointsNew[m].rank = rrank; 9078 } 9079 } else if ((p >= cMax) && (p < cEnd)) { 9080 /* Old hybrid cells add new cells and hybrid face */ 9081 for (r = 0; r < 2; ++r, ++m) { 9082 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9083 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9084 remotePointsNew[m].rank = rrank; 9085 } 9086 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9087 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]); 9088 remotePointsNew[m].rank = rrank; 9089 ++m; 9090 } 9091 break; 9092 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9093 case REFINER_SIMPLEX_TO_HEX_2D: 9094 if ((p >= vStart) && (p < vEnd)) { 9095 /* Old vertices stay the same */ 9096 localPointsNew[m] = vStartNew + (p - vStart); 9097 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9098 remotePointsNew[m].rank = rrank; 9099 ++m; 9100 } else if ((p >= fStart) && (p < fEnd)) { 9101 /* Old interior faces add new faces and vertex */ 9102 for (r = 0; r < 2; ++r, ++m) { 9103 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9104 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9105 remotePointsNew[m].rank = rrank; 9106 } 9107 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9108 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9109 remotePointsNew[m].rank = rrank; 9110 ++m; 9111 } else if ((p >= cStart) && (p < cMax)) { 9112 /* Old interior cells add new cells, interior faces, and a vertex */ 9113 for (r = 0; r < 3; ++r, ++m) { 9114 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 9115 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 9116 remotePointsNew[m].rank = rrank; 9117 } 9118 for (r = 0; r < 3; ++r, ++m) { 9119 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9120 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 9121 remotePointsNew[m].rank = rrank; 9122 } 9123 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9124 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9125 remotePointsNew[m].rank = rrank; 9126 ++m; 9127 } else if ((p >= cMax) && (p < cEnd)) { 9128 /* Old interior hybrid cells add new cells, interior faces, and a vertex */ 9129 for (r = 0; r < 4; ++r, ++m) { 9130 localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9131 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9132 remotePointsNew[m].rank = rrank; 9133 } 9134 for (r = 0; r < 4; ++r, ++m) { 9135 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9136 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9137 remotePointsNew[m].rank = rrank; 9138 } 9139 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9140 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9141 remotePointsNew[m].rank = rrank; 9142 ++m; 9143 } 9144 break; 9145 case REFINER_HEX_2D: 9146 case REFINER_HYBRID_HEX_2D: 9147 if ((p >= vStart) && (p < vEnd)) { 9148 /* Old vertices stay the same */ 9149 localPointsNew[m] = vStartNew + (p - vStart); 9150 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9151 remotePointsNew[m].rank = rrank; 9152 ++m; 9153 } else if ((p >= fStart) && (p < fMax)) { 9154 /* Old interior faces add new faces and vertex */ 9155 for (r = 0; r < 2; ++r, ++m) { 9156 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9157 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9158 remotePointsNew[m].rank = rrank; 9159 } 9160 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9161 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9162 remotePointsNew[m].rank = rrank; 9163 ++m; 9164 } else if ((p >= fMax) && (p < fEnd)) { 9165 /* Old hybrid faces stay the same */ 9166 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9167 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9168 remotePointsNew[m].rank = rrank; 9169 ++m; 9170 } else if ((p >= cStart) && (p < cMax)) { 9171 /* Old interior cells add new cells, interior faces, and vertex */ 9172 for (r = 0; r < 4; ++r, ++m) { 9173 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9174 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9175 remotePointsNew[m].rank = rrank; 9176 } 9177 for (r = 0; r < 4; ++r, ++m) { 9178 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 9179 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 9180 remotePointsNew[m].rank = rrank; 9181 } 9182 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 9183 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 9184 remotePointsNew[m].rank = rrank; 9185 ++m; 9186 } else if ((p >= cStart) && (p < cMax)) { 9187 /* Old hybrid cells add new cells and hybrid face */ 9188 for (r = 0; r < 2; ++r, ++m) { 9189 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */ 9190 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */ 9191 remotePointsNew[m].rank = rrank; 9192 } 9193 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9194 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]); 9195 remotePointsNew[m].rank = rrank; 9196 ++m; 9197 } 9198 break; 9199 case REFINER_SIMPLEX_3D: 9200 case REFINER_HYBRID_SIMPLEX_3D: 9201 if ((p >= vStart) && (p < vEnd)) { 9202 /* Interior vertices stay the same */ 9203 localPointsNew[m] = vStartNew + (p - vStart); 9204 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9205 remotePointsNew[m].rank = rrank; 9206 ++m; 9207 } else if ((p >= eStart) && (p < eMax)) { 9208 /* Interior edges add new edges and vertex */ 9209 for (r = 0; r < 2; ++r, ++m) { 9210 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9211 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9212 remotePointsNew[m].rank = rrank; 9213 } 9214 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9215 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9216 remotePointsNew[m].rank = rrank; 9217 ++m; 9218 } else if ((p >= eMax) && (p < eEnd)) { 9219 /* Hybrid edges stay the same */ 9220 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9221 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]); 9222 remotePointsNew[m].rank = rrank; 9223 ++m; 9224 } else if ((p >= fStart) && (p < fMax)) { 9225 /* Interior faces add new faces and edges */ 9226 for (r = 0; r < 4; ++r, ++m) { 9227 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9228 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9229 remotePointsNew[m].rank = rrank; 9230 } 9231 for (r = 0; r < 3; ++r, ++m) { 9232 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9233 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9234 remotePointsNew[m].rank = rrank; 9235 } 9236 } else if ((p >= fMax) && (p < fEnd)) { 9237 /* Hybrid faces add new faces and edges */ 9238 for (r = 0; r < 2; ++r, ++m) { 9239 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9240 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; 9241 remotePointsNew[m].rank = rrank; 9242 } 9243 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 9244 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]); 9245 remotePointsNew[m].rank = rrank; 9246 ++m; 9247 } else if ((p >= cStart) && (p < cMax)) { 9248 /* Interior cells add new cells, faces, and edges */ 9249 for (r = 0; r < 8; ++r, ++m) { 9250 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9251 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9252 remotePointsNew[m].rank = rrank; 9253 } 9254 for (r = 0; r < 8; ++r, ++m) { 9255 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9256 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 9257 remotePointsNew[m].rank = rrank; 9258 } 9259 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 9260 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; 9261 remotePointsNew[m].rank = rrank; 9262 ++m; 9263 } else if ((p >= cMax) && (p < cEnd)) { 9264 /* Hybrid cells add new cells and faces */ 9265 for (r = 0; r < 4; ++r, ++m) { 9266 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9267 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9268 remotePointsNew[m].rank = rrank; 9269 } 9270 for (r = 0; r < 3; ++r, ++m) { 9271 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9272 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; 9273 remotePointsNew[m].rank = rrank; 9274 } 9275 } 9276 break; 9277 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9278 case REFINER_SIMPLEX_TO_HEX_3D: 9279 if ((p >= vStart) && (p < vEnd)) { 9280 /* Interior vertices stay the same */ 9281 localPointsNew[m] = vStartNew + (p - vStart); 9282 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9283 remotePointsNew[m].rank = rrank; 9284 ++m; 9285 } else if ((p >= eStart) && (p < eMax)) { 9286 /* Interior edges add new edges and vertex */ 9287 for (r = 0; r < 2; ++r, ++m) { 9288 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9289 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9290 remotePointsNew[m].rank = rrank; 9291 } 9292 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9293 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9294 remotePointsNew[m].rank = rrank; 9295 ++m; 9296 } else if ((p >= eMax) && (p < eEnd)) { 9297 /* Hybrid edges stay the same */ 9298 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax); 9299 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])*4 + (rp - rdepthMaxOld[n*(depth+1)+1]); 9300 remotePointsNew[m].rank = rrank; 9301 ++m; 9302 } else if ((p >= fStart) && (p < fMax)) { 9303 /* Interior faces add new faces, edges and a vertex */ 9304 for (r = 0; r < 3; ++r, ++m) { 9305 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 9306 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 9307 remotePointsNew[m].rank = rrank; 9308 } 9309 for (r = 0; r < 3; ++r, ++m) { 9310 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9311 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9312 remotePointsNew[m].rank = rrank; 9313 } 9314 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9315 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9316 remotePointsNew[m].rank = rrank; 9317 ++m; 9318 } else if ((p >= fMax) && (p < fEnd)) { 9319 /* Interior hybrid faces add new faces and an edge */ 9320 for (r = 0; r < 2; ++r, ++m) { 9321 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9322 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rp - rdepthMaxOld[n*(depth+1)+depth-1])*2 + r; 9323 remotePointsNew[m].rank = rrank; 9324 } 9325 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9326 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])*4 + (rdepthSizeOld[n*(depth+1)+1]+reStart[n] - rdepthMaxOld[n*(depth+1)+1]) + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9327 remotePointsNew[m].rank = rrank; 9328 ++m; 9329 } else if ((p >= cStart) && (p < cMax)) { 9330 /* Interior cells add new cells, faces, edges, and a vertex */ 9331 for (r = 0; r < 4; ++r, ++m) { 9332 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9333 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9334 remotePointsNew[m].rank = rrank; 9335 } 9336 for (r = 0; r < 6; ++r, ++m) { 9337 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9338 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r; 9339 remotePointsNew[m].rank = rrank; 9340 } 9341 for (r = 0; r < 4; ++r, ++m) { 9342 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9343 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])*4 + r; 9344 remotePointsNew[m].rank = rrank; 9345 } 9346 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 9347 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1]- reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n]) + (rp - rcStart[n]); 9348 remotePointsNew[m].rank = rrank; 9349 ++m; 9350 } else if ((p >= cMax) && (p < cEnd)) { 9351 /* Interior hybrid cells add new cells, faces and an edge */ 9352 for (r = 0; r < 3; ++r, ++m) { 9353 localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9354 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9355 remotePointsNew[m].rank = rrank; 9356 } 9357 for (r = 0; r < 3; ++r, ++m) { 9358 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9359 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*6 + (rdepthSizeOld[n*(depth+1)+depth-1]+rfStart[n] - rdepthMaxOld[n*(depth+1)+depth-1])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9360 remotePointsNew[m].rank = rrank; 9361 } 9362 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9363 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])*4 + (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]); 9364 remotePointsNew[m].rank = rrank; 9365 ++m; 9366 } 9367 break; 9368 case REFINER_HEX_3D: 9369 case REFINER_HYBRID_HEX_3D: 9370 if ((p >= vStart) && (p < vEnd)) { 9371 /* Interior vertices stay the same */ 9372 localPointsNew[m] = vStartNew + (p - vStart); 9373 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9374 remotePointsNew[m].rank = rrank; 9375 ++m; 9376 } else if ((p >= eStart) && (p < eMax)) { 9377 /* Interior edges add new edges and vertex */ 9378 for (r = 0; r < 2; ++r, ++m) { 9379 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9380 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9381 remotePointsNew[m].rank = rrank; 9382 } 9383 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9384 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9385 remotePointsNew[m].rank = rrank; 9386 ++m; 9387 } else if ((p >= eMax) && (p < eEnd)) { 9388 /* Hybrid edges stay the same */ 9389 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 9390 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]); 9391 remotePointsNew[m].rank = rrank; 9392 ++m; 9393 } else if ((p >= fStart) && (p < fMax)) { 9394 /* Interior faces add new faces, edges, and vertex */ 9395 for (r = 0; r < 4; ++r, ++m) { 9396 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9397 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9398 remotePointsNew[m].rank = rrank; 9399 } 9400 for (r = 0; r < 4; ++r, ++m) { 9401 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 9402 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 9403 remotePointsNew[m].rank = rrank; 9404 } 9405 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9406 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9407 remotePointsNew[m].rank = rrank; 9408 ++m; 9409 } else if ((p >= fMax) && (p < fEnd)) { 9410 /* Hybrid faces add new faces and edges */ 9411 for (r = 0; r < 2; ++r, ++m) { 9412 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 9413 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; 9414 remotePointsNew[m].rank = rrank; 9415 } 9416 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 9417 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]); 9418 remotePointsNew[m].rank = rrank; 9419 ++m; 9420 } else if ((p >= cStart) && (p < cMax)) { 9421 /* Interior cells add new cells, faces, edges, and vertex */ 9422 for (r = 0; r < 8; ++r, ++m) { 9423 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9424 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9425 remotePointsNew[m].rank = rrank; 9426 } 9427 for (r = 0; r < 12; ++r, ++m) { 9428 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 9429 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 9430 remotePointsNew[m].rank = rrank; 9431 } 9432 for (r = 0; r < 6; ++r, ++m) { 9433 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 9434 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; 9435 remotePointsNew[m].rank = rrank; 9436 } 9437 for (r = 0; r < 1; ++r, ++m) { 9438 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 9439 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 9440 remotePointsNew[m].rank = rrank; 9441 } 9442 } else if ((p >= cMax) && (p < cEnd)) { 9443 /* Hybrid cells add new cells, faces, and edges */ 9444 for (r = 0; r < 4; ++r, ++m) { 9445 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9446 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9447 remotePointsNew[m].rank = rrank; 9448 } 9449 for (r = 0; r < 4; ++r, ++m) { 9450 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 9451 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; 9452 remotePointsNew[m].rank = rrank; 9453 } 9454 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9455 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]); 9456 remotePointsNew[m].rank = rrank; 9457 ++m; 9458 } 9459 break; 9460 default: 9461 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 9462 } 9463 } 9464 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %d should be %d", m, numLeavesNew); 9465 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 9466 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 9467 { 9468 PetscSFNode *rp, *rtmp; 9469 PetscInt *lp, *idx, *ltmp, i; 9470 9471 /* SF needs sorted leaves to correct calculate Gather */ 9472 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 9473 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 9474 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 9475 for (i = 0; i < numLeavesNew; ++i) { 9476 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); 9477 idx[i] = i; 9478 } 9479 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 9480 for (i = 0; i < numLeavesNew; ++i) { 9481 lp[i] = localPointsNew[idx[i]]; 9482 rp[i] = remotePointsNew[idx[i]]; 9483 } 9484 ltmp = localPointsNew; 9485 localPointsNew = lp; 9486 rtmp = remotePointsNew; 9487 remotePointsNew = rp; 9488 ierr = PetscFree(idx);CHKERRQ(ierr); 9489 ierr = PetscFree(ltmp);CHKERRQ(ierr); 9490 ierr = PetscFree(rtmp);CHKERRQ(ierr); 9491 } 9492 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 9493 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 9494 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 9495 PetscFunctionReturn(0); 9496 } 9497 9498 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 9499 { 9500 PetscInt numLabels, l; 9501 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 9502 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 9503 PetscErrorCode ierr; 9504 9505 PetscFunctionBegin; 9506 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 9507 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 9508 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9509 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 9510 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 9511 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 9512 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 9513 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 9514 switch (refiner) { 9515 case REFINER_NOOP: 9516 case REFINER_SIMPLEX_1D: 9517 case REFINER_SIMPLEX_2D: 9518 case REFINER_SIMPLEX_TO_HEX_2D: 9519 case REFINER_HEX_2D: 9520 case REFINER_SIMPLEX_3D: 9521 case REFINER_HEX_3D: 9522 case REFINER_SIMPLEX_TO_HEX_3D: 9523 break; 9524 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9525 case REFINER_HYBRID_SIMPLEX_3D: 9526 case REFINER_HYBRID_HEX_3D: 9527 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 9528 case REFINER_HYBRID_SIMPLEX_2D: 9529 case REFINER_HYBRID_HEX_2D: 9530 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 9531 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9532 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 9533 break; 9534 default: 9535 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 9536 } 9537 cMax = cMax < 0 ? cEnd : cMax; 9538 fMax = fMax < 0 ? fEnd : fMax; 9539 eMax = eMax < 0 ? eEnd : eMax; 9540 for (l = 0; l < numLabels; ++l) { 9541 DMLabel label, labelNew; 9542 const char *lname; 9543 PetscBool isDepth; 9544 IS valueIS; 9545 const PetscInt *values; 9546 PetscInt defVal; 9547 PetscInt numValues, val; 9548 9549 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 9550 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 9551 if (isDepth) continue; 9552 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 9553 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 9554 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 9555 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 9556 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 9557 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 9558 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 9559 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 9560 for (val = 0; val < numValues; ++val) { 9561 IS pointIS; 9562 const PetscInt *points; 9563 PetscInt numPoints, n; 9564 9565 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 9566 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 9567 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 9568 /* Ensure refined label is created with same number of strata as 9569 * original (even if no entries here). */ 9570 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 9571 for (n = 0; n < numPoints; ++n) { 9572 const PetscInt p = points[n]; 9573 switch (refiner) { 9574 case REFINER_SIMPLEX_1D: 9575 if ((p >= vStart) && (p < vEnd)) { 9576 /* Old vertices stay the same */ 9577 newp = vStartNew + (p - vStart); 9578 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9579 } else if ((p >= cStart) && (p < cEnd)) { 9580 /* Old cells add new cells and vertex */ 9581 newp = vStartNew + (vEnd - vStart) + (p - cStart); 9582 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9583 for (r = 0; r < 2; ++r) { 9584 newp = cStartNew + (p - cStart)*2 + r; 9585 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9586 } 9587 } 9588 break; 9589 case REFINER_SIMPLEX_2D: 9590 if ((p >= vStart) && (p < vEnd)) { 9591 /* Old vertices stay the same */ 9592 newp = vStartNew + (p - vStart); 9593 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9594 } else if ((p >= fStart) && (p < fEnd)) { 9595 /* Old faces add new faces and vertex */ 9596 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9597 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9598 for (r = 0; r < 2; ++r) { 9599 newp = fStartNew + (p - fStart)*2 + r; 9600 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9601 } 9602 } else if ((p >= cStart) && (p < cEnd)) { 9603 /* Old cells add new cells and interior faces */ 9604 for (r = 0; r < 4; ++r) { 9605 newp = cStartNew + (p - cStart)*4 + r; 9606 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9607 } 9608 for (r = 0; r < 3; ++r) { 9609 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9610 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9611 } 9612 } 9613 break; 9614 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9615 case REFINER_SIMPLEX_TO_HEX_2D: 9616 if ((p >= vStart) && (p < vEnd)) { 9617 /* Old vertices stay the same */ 9618 newp = vStartNew + (p - vStart); 9619 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9620 } else if ((p >= fStart) && (p < fEnd)) { 9621 /* Old faces add new faces and vertex */ 9622 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9623 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9624 for (r = 0; r < 2; ++r) { 9625 newp = fStartNew + (p - fStart)*2 + r; 9626 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9627 } 9628 } else if ((p >= cStart) && (p < cMax)) { 9629 /* Old cells add new cells, interior faces, and a vertex */ 9630 for (r = 0; r < 3; ++r) { 9631 newp = cStartNew + (p - cStart)*3 + r; 9632 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9633 } 9634 for (r = 0; r < 3; ++r) { 9635 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9636 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9637 } 9638 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9639 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9640 } else if ((p >= cMax) && (p < cEnd)) { 9641 /* Old hybrid cells add new cells, interior faces, and a vertex */ 9642 for (r = 0; r < 4; ++r) { 9643 newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9644 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9645 } 9646 for (r = 0; r < 4; ++r) { 9647 newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9648 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9649 } 9650 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9651 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9652 } 9653 break; 9654 case REFINER_HEX_2D: 9655 if ((p >= vStart) && (p < vEnd)) { 9656 /* Old vertices stay the same */ 9657 newp = vStartNew + (p - vStart); 9658 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9659 } else if ((p >= fStart) && (p < fEnd)) { 9660 /* Old faces add new faces and vertex */ 9661 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9662 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9663 for (r = 0; r < 2; ++r) { 9664 newp = fStartNew + (p - fStart)*2 + r; 9665 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9666 } 9667 } else if ((p >= cStart) && (p < cEnd)) { 9668 /* Old cells add new cells and interior faces and vertex */ 9669 for (r = 0; r < 4; ++r) { 9670 newp = cStartNew + (p - cStart)*4 + r; 9671 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9672 } 9673 for (r = 0; r < 4; ++r) { 9674 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9675 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9676 } 9677 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9678 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9679 } 9680 break; 9681 case REFINER_HYBRID_SIMPLEX_2D: 9682 if ((p >= vStart) && (p < vEnd)) { 9683 /* Old vertices stay the same */ 9684 newp = vStartNew + (p - vStart); 9685 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9686 } else if ((p >= fStart) && (p < fMax)) { 9687 /* Old interior faces add new faces and vertex */ 9688 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9689 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9690 for (r = 0; r < 2; ++r) { 9691 newp = fStartNew + (p - fStart)*2 + r; 9692 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9693 } 9694 } else if ((p >= fMax) && (p < fEnd)) { 9695 /* Old hybrid faces stay the same */ 9696 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9697 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9698 } else if ((p >= cStart) && (p < cMax)) { 9699 /* Old interior cells add new cells and interior faces */ 9700 for (r = 0; r < 4; ++r) { 9701 newp = cStartNew + (p - cStart)*4 + r; 9702 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9703 } 9704 for (r = 0; r < 3; ++r) { 9705 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9706 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9707 } 9708 } else if ((p >= cMax) && (p < cEnd)) { 9709 /* Old hybrid cells add new cells and hybrid face */ 9710 for (r = 0; r < 2; ++r) { 9711 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9712 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9713 } 9714 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9715 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9716 } 9717 break; 9718 case REFINER_HYBRID_HEX_2D: 9719 if ((p >= vStart) && (p < vEnd)) { 9720 /* Old vertices stay the same */ 9721 newp = vStartNew + (p - vStart); 9722 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9723 } else if ((p >= fStart) && (p < fMax)) { 9724 /* Old interior faces add new faces and vertex */ 9725 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9726 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9727 for (r = 0; r < 2; ++r) { 9728 newp = fStartNew + (p - fStart)*2 + r; 9729 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9730 } 9731 } else if ((p >= fMax) && (p < fEnd)) { 9732 /* Old hybrid faces stay the same */ 9733 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9734 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9735 } else if ((p >= cStart) && (p < cMax)) { 9736 /* Old interior cells add new cells, interior faces, and vertex */ 9737 for (r = 0; r < 4; ++r) { 9738 newp = cStartNew + (p - cStart)*4 + r; 9739 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9740 } 9741 for (r = 0; r < 4; ++r) { 9742 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9743 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9744 } 9745 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9746 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9747 } else if ((p >= cMax) && (p < cEnd)) { 9748 /* Old hybrid cells add new cells and hybrid face */ 9749 for (r = 0; r < 2; ++r) { 9750 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9751 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9752 } 9753 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9754 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9755 } 9756 break; 9757 case REFINER_SIMPLEX_3D: 9758 if ((p >= vStart) && (p < vEnd)) { 9759 /* Old vertices stay the same */ 9760 newp = vStartNew + (p - vStart); 9761 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9762 } else if ((p >= eStart) && (p < eEnd)) { 9763 /* Old edges add new edges and vertex */ 9764 for (r = 0; r < 2; ++r) { 9765 newp = eStartNew + (p - eStart)*2 + r; 9766 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9767 } 9768 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9769 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9770 } else if ((p >= fStart) && (p < fEnd)) { 9771 /* Old faces add new faces and edges */ 9772 for (r = 0; r < 4; ++r) { 9773 newp = fStartNew + (p - fStart)*4 + r; 9774 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9775 } 9776 for (r = 0; r < 3; ++r) { 9777 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 9778 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9779 } 9780 } else if ((p >= cStart) && (p < cEnd)) { 9781 /* Old cells add new cells and interior faces and edges */ 9782 for (r = 0; r < 8; ++r) { 9783 newp = cStartNew + (p - cStart)*8 + r; 9784 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9785 } 9786 for (r = 0; r < 8; ++r) { 9787 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 9788 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9789 } 9790 for (r = 0; r < 1; ++r) { 9791 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 9792 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9793 } 9794 } 9795 break; 9796 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9797 case REFINER_SIMPLEX_TO_HEX_3D: 9798 if ((p >= vStart) && (p < vEnd)) { 9799 /* Old vertices stay the same */ 9800 newp = vStartNew + (p - vStart); 9801 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9802 } else if ((p >= eStart) && (p < eMax)) { 9803 /* Interior edges add new edges and vertex */ 9804 for (r = 0; r < 2; ++r) { 9805 newp = eStartNew + (p - eStart)*2 + r; 9806 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9807 } 9808 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9809 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9810 } else if ((p >= eMax) && (p < eEnd)) { 9811 /* Hybrid edges stay the same */ 9812 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax; 9813 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9814 } else if ((p >= fStart) && (p < fMax)) { 9815 /* Old faces add new faces, edges and a vertex */ 9816 for (r = 0; r < 3; ++r) { 9817 newp = fStartNew + (p - fStart)*3 + r; 9818 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9819 } 9820 for (r = 0; r < 3; ++r) { 9821 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9822 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9823 } 9824 } else if ((p >= fMax) && (p < fEnd)) { 9825 /* Old hybrid faces add new faces and an edge */ 9826 for (r = 0; r < 2; ++r) { 9827 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9828 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9829 } 9830 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9831 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9832 } else if ((p >= cStart) && (p < cMax)) { 9833 /* Old cells add new cells and interior faces and edges and a vertex */ 9834 for (r = 0; r < 4; ++r) { 9835 newp = cStartNew + (p - cStart)*4 + r; 9836 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9837 } 9838 for (r = 0; r < 6; ++r) { 9839 newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9840 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9841 } 9842 for (r = 0; r < 4; ++r) { 9843 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9844 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9845 } 9846 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart; 9847 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9848 } else if ((p >= cMax) && (p < cEnd)) { 9849 /* Old hybrid cells add new cells and interior faces and an edge */ 9850 for (r = 0; r < 3; ++r) { 9851 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9852 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9853 } 9854 for (r = 0; r < 3; ++r) { 9855 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9856 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9857 } 9858 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax; 9859 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9860 } 9861 break; 9862 case REFINER_HYBRID_SIMPLEX_3D: 9863 if ((p >= vStart) && (p < vEnd)) { 9864 /* Interior vertices stay the same */ 9865 newp = vStartNew + (p - vStart); 9866 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9867 } else if ((p >= eStart) && (p < eMax)) { 9868 /* Interior edges add new edges and vertex */ 9869 for (r = 0; r < 2; ++r) { 9870 newp = eStartNew + (p - eStart)*2 + r; 9871 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9872 } 9873 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9874 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9875 } else if ((p >= eMax) && (p < eEnd)) { 9876 /* Hybrid edges stay the same */ 9877 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9878 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9879 } else if ((p >= fStart) && (p < fMax)) { 9880 /* Interior faces add new faces and edges */ 9881 for (r = 0; r < 4; ++r) { 9882 newp = fStartNew + (p - fStart)*4 + r; 9883 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9884 } 9885 for (r = 0; r < 3; ++r) { 9886 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9887 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9888 } 9889 } else if ((p >= fMax) && (p < fEnd)) { 9890 /* Hybrid faces add new faces and edges */ 9891 for (r = 0; r < 2; ++r) { 9892 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9893 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9894 } 9895 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 9896 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9897 } else if ((p >= cStart) && (p < cMax)) { 9898 /* Interior cells add new cells, faces, and edges */ 9899 for (r = 0; r < 8; ++r) { 9900 newp = cStartNew + (p - cStart)*8 + r; 9901 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9902 } 9903 for (r = 0; r < 8; ++r) { 9904 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9905 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9906 } 9907 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 9908 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9909 } else if ((p >= cMax) && (p < cEnd)) { 9910 /* Hybrid cells add new cells and faces */ 9911 for (r = 0; r < 4; ++r) { 9912 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9913 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9914 } 9915 for (r = 0; r < 3; ++r) { 9916 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9917 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9918 } 9919 } 9920 break; 9921 case REFINER_HEX_3D: 9922 if ((p >= vStart) && (p < vEnd)) { 9923 /* Old vertices stay the same */ 9924 newp = vStartNew + (p - vStart); 9925 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9926 } else if ((p >= eStart) && (p < eEnd)) { 9927 /* Old edges add new edges and vertex */ 9928 for (r = 0; r < 2; ++r) { 9929 newp = eStartNew + (p - eStart)*2 + r; 9930 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9931 } 9932 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9933 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9934 } else if ((p >= fStart) && (p < fEnd)) { 9935 /* Old faces add new faces, edges, and vertex */ 9936 for (r = 0; r < 4; ++r) { 9937 newp = fStartNew + (p - fStart)*4 + r; 9938 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9939 } 9940 for (r = 0; r < 4; ++r) { 9941 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 9942 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9943 } 9944 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 9945 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9946 } else if ((p >= cStart) && (p < cEnd)) { 9947 /* Old cells add new cells, faces, edges, and vertex */ 9948 for (r = 0; r < 8; ++r) { 9949 newp = cStartNew + (p - cStart)*8 + r; 9950 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9951 } 9952 for (r = 0; r < 12; ++r) { 9953 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 9954 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9955 } 9956 for (r = 0; r < 6; ++r) { 9957 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 9958 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9959 } 9960 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 9961 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9962 } 9963 break; 9964 case REFINER_HYBRID_HEX_3D: 9965 if ((p >= vStart) && (p < vEnd)) { 9966 /* Interior vertices stay the same */ 9967 newp = vStartNew + (p - vStart); 9968 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9969 } else if ((p >= eStart) && (p < eMax)) { 9970 /* Interior edges add new edges and vertex */ 9971 for (r = 0; r < 2; ++r) { 9972 newp = eStartNew + (p - eStart)*2 + r; 9973 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9974 } 9975 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9976 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9977 } else if ((p >= eMax) && (p < eEnd)) { 9978 /* Hybrid edges stay the same */ 9979 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 9980 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9981 } else if ((p >= fStart) && (p < fMax)) { 9982 /* Interior faces add new faces, edges, and vertex */ 9983 for (r = 0; r < 4; ++r) { 9984 newp = fStartNew + (p - fStart)*4 + r; 9985 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9986 } 9987 for (r = 0; r < 4; ++r) { 9988 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 9989 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9990 } 9991 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9992 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9993 } else if ((p >= fMax) && (p < fEnd)) { 9994 /* Hybrid faces add new faces and edges */ 9995 for (r = 0; r < 2; ++r) { 9996 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 9997 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9998 } 9999 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 10000 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10001 } else if ((p >= cStart) && (p < cMax)) { 10002 /* Interior cells add new cells, faces, edges, and vertex */ 10003 for (r = 0; r < 8; ++r) { 10004 newp = cStartNew + (p - cStart)*8 + r; 10005 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10006 } 10007 for (r = 0; r < 12; ++r) { 10008 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 10009 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10010 } 10011 for (r = 0; r < 6; ++r) { 10012 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 10013 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10014 } 10015 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 10016 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10017 } else if ((p >= cMax) && (p < cEnd)) { 10018 /* Hybrid cells add new cells, faces, and edges */ 10019 for (r = 0; r < 4; ++r) { 10020 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10021 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10022 } 10023 for (r = 0; r < 4; ++r) { 10024 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 10025 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10026 } 10027 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 10028 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10029 } 10030 break; 10031 default: 10032 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", refiner); 10033 } 10034 } 10035 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 10036 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 10037 } 10038 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 10039 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 10040 if (0) { 10041 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 10042 } 10043 } 10044 PetscFunctionReturn(0); 10045 } 10046 10047 /* This will only work for interpolated meshes */ 10048 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 10049 { 10050 DM rdm; 10051 PetscInt *depthSize; 10052 PetscInt dim, depth = 0, d, pStart = 0, pEnd = 0; 10053 PetscErrorCode ierr; 10054 10055 PetscFunctionBegin; 10056 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 10057 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 10058 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10059 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 10060 /* Calculate number of new points of each depth */ 10061 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10062 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 10063 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10064 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 10065 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10066 /* Step 1: Set chart */ 10067 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 10068 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 10069 /* Step 2: Set cone/support sizes (automatically stratifies) */ 10070 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10071 /* Step 3: Setup refined DM */ 10072 ierr = DMSetUp(rdm);CHKERRQ(ierr); 10073 /* Step 4: Set cones and supports (automatically symmetrizes) */ 10074 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10075 /* Step 5: Create pointSF */ 10076 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10077 /* Step 6: Create labels */ 10078 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10079 /* Step 7: Set coordinates */ 10080 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10081 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10082 10083 *dmRefined = rdm; 10084 PetscFunctionReturn(0); 10085 } 10086 10087 /*@ 10088 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 10089 10090 Input Parameter: 10091 . dm - The coarse DM 10092 10093 Output Parameter: 10094 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 10095 10096 Level: developer 10097 10098 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 10099 @*/ 10100 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 10101 { 10102 CellRefiner cellRefiner; 10103 PetscInt *depthSize, *fpoints; 10104 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 10105 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 10106 PetscErrorCode ierr; 10107 10108 PetscFunctionBegin; 10109 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10110 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 10111 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 10112 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10113 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10114 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10115 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 10116 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 10117 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 10118 switch (cellRefiner) { 10119 case REFINER_SIMPLEX_1D: 10120 case REFINER_SIMPLEX_2D: 10121 case REFINER_HYBRID_SIMPLEX_2D: 10122 case REFINER_HEX_2D: 10123 case REFINER_HYBRID_HEX_2D: 10124 case REFINER_SIMPLEX_3D: 10125 case REFINER_HYBRID_SIMPLEX_3D: 10126 case REFINER_HEX_3D: 10127 case REFINER_HYBRID_HEX_3D: 10128 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 10129 break; 10130 default: 10131 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %d", cellRefiner); 10132 } 10133 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 10134 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10135 PetscFunctionReturn(0); 10136 } 10137 10138 /*@ 10139 DMPlexSetRefinementUniform - Set the flag for uniform refinement 10140 10141 Input Parameters: 10142 + dm - The DM 10143 - refinementUniform - The flag for uniform refinement 10144 10145 Level: developer 10146 10147 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10148 @*/ 10149 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 10150 { 10151 DM_Plex *mesh = (DM_Plex*) dm->data; 10152 10153 PetscFunctionBegin; 10154 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10155 mesh->refinementUniform = refinementUniform; 10156 PetscFunctionReturn(0); 10157 } 10158 10159 /*@ 10160 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 10161 10162 Input Parameter: 10163 . dm - The DM 10164 10165 Output Parameter: 10166 . refinementUniform - The flag for uniform refinement 10167 10168 Level: developer 10169 10170 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10171 @*/ 10172 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 10173 { 10174 DM_Plex *mesh = (DM_Plex*) dm->data; 10175 10176 PetscFunctionBegin; 10177 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10178 PetscValidPointer(refinementUniform, 2); 10179 *refinementUniform = mesh->refinementUniform; 10180 PetscFunctionReturn(0); 10181 } 10182 10183 /*@ 10184 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 10185 10186 Input Parameters: 10187 + dm - The DM 10188 - refinementLimit - The maximum cell volume in the refined mesh 10189 10190 Level: developer 10191 10192 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10193 @*/ 10194 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 10195 { 10196 DM_Plex *mesh = (DM_Plex*) dm->data; 10197 10198 PetscFunctionBegin; 10199 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10200 mesh->refinementLimit = refinementLimit; 10201 PetscFunctionReturn(0); 10202 } 10203 10204 /*@ 10205 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 10206 10207 Input Parameter: 10208 . dm - The DM 10209 10210 Output Parameter: 10211 . refinementLimit - The maximum cell volume in the refined mesh 10212 10213 Level: developer 10214 10215 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10216 @*/ 10217 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 10218 { 10219 DM_Plex *mesh = (DM_Plex*) dm->data; 10220 10221 PetscFunctionBegin; 10222 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10223 PetscValidPointer(refinementLimit, 2); 10224 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 10225 *refinementLimit = mesh->refinementLimit; 10226 PetscFunctionReturn(0); 10227 } 10228 10229 /*@ 10230 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 10231 10232 Input Parameters: 10233 + dm - The DM 10234 - refinementFunc - Function giving the maximum cell volume in the refined mesh 10235 10236 Note: The calling sequence is refinementFunc(coords, limit) 10237 $ coords - Coordinates of the current point, usually a cell centroid 10238 $ limit - The maximum cell volume for a cell containing this point 10239 10240 Level: developer 10241 10242 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10243 @*/ 10244 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 10245 { 10246 DM_Plex *mesh = (DM_Plex*) dm->data; 10247 10248 PetscFunctionBegin; 10249 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10250 mesh->refinementFunc = refinementFunc; 10251 PetscFunctionReturn(0); 10252 } 10253 10254 /*@ 10255 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 10256 10257 Input Parameter: 10258 . dm - The DM 10259 10260 Output Parameter: 10261 . refinementFunc - Function giving the maximum cell volume in the refined mesh 10262 10263 Note: The calling sequence is refinementFunc(coords, limit) 10264 $ coords - Coordinates of the current point, usually a cell centroid 10265 $ limit - The maximum cell volume for a cell containing this point 10266 10267 Level: developer 10268 10269 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10270 @*/ 10271 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 10272 { 10273 DM_Plex *mesh = (DM_Plex*) dm->data; 10274 10275 PetscFunctionBegin; 10276 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10277 PetscValidPointer(refinementFunc, 2); 10278 *refinementFunc = mesh->refinementFunc; 10279 PetscFunctionReturn(0); 10280 } 10281 10282 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 10283 { 10284 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 10285 PetscErrorCode ierr; 10286 10287 PetscFunctionBegin; 10288 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10289 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 10290 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 10291 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 10292 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 10293 switch (dim) { 10294 case 1: 10295 switch (coneSize) { 10296 case 2: 10297 *cellRefiner = REFINER_SIMPLEX_1D; 10298 break; 10299 default: 10300 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 10301 } 10302 break; 10303 case 2: 10304 switch (coneSize) { 10305 case 3: 10306 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 10307 else *cellRefiner = REFINER_SIMPLEX_2D; 10308 break; 10309 case 4: 10310 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 10311 else *cellRefiner = REFINER_HEX_2D; 10312 break; 10313 default: 10314 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 10315 } 10316 break; 10317 case 3: 10318 switch (coneSize) { 10319 case 4: 10320 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 10321 else *cellRefiner = REFINER_SIMPLEX_3D; 10322 break; 10323 case 5: 10324 if (cMax == 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 10325 else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 10326 break; 10327 case 6: 10328 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 10329 else *cellRefiner = REFINER_HEX_3D; 10330 break; 10331 default: 10332 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %d in dimension %d for cell refiner", coneSize, dim); 10333 } 10334 break; 10335 default: 10336 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %d for cell refiner", dim); 10337 } 10338 PetscFunctionReturn(0); 10339 } 10340 10341 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 10342 { 10343 PetscBool isUniform; 10344 PetscErrorCode ierr; 10345 10346 PetscFunctionBegin; 10347 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10348 if (isUniform) { 10349 CellRefiner cellRefiner; 10350 PetscBool localized; 10351 10352 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10353 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10354 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 10355 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 10356 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 10357 } else { 10358 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 10359 } 10360 PetscFunctionReturn(0); 10361 } 10362 10363 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 10364 { 10365 DM cdm = dm; 10366 PetscInt r; 10367 PetscBool isUniform, localized; 10368 PetscErrorCode ierr; 10369 10370 PetscFunctionBegin; 10371 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10372 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10373 if (isUniform) { 10374 for (r = 0; r < nlevels; ++r) { 10375 CellRefiner cellRefiner; 10376 10377 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 10378 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 10379 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10380 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10381 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10382 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 10383 cdm = dmRefined[r]; 10384 } 10385 } else { 10386 for (r = 0; r < nlevels; ++r) { 10387 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 10388 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10389 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10390 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10391 cdm = dmRefined[r]; 10392 } 10393 } 10394 PetscFunctionReturn(0); 10395 } 10396