1 #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2 #include <petscsf.h> 3 4 const char * const CellRefiners[] = {"NOOP", "SIMPLEX_1D", "SIMPLEX_2D", "HYBRID_SIMPLEX_2D", "SIMPLEX_TO_HEX_2D", "HYBRID_SIMPLEX_TO_HEX_2D", "HEX_2D", "HYBRID_HEX_2D", 5 "SIMPLEX_3D", "HYBRID_SIMPLEX_3D", "SIMPLEX_TO_HEX_3D", "HYBRID_SIMPLEX_TO_HEX_3D", "HEX_3D", "HYBRID_HEX_3D", "CellRefiners", "REFINER_", 0}; 6 7 PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 8 { 9 PetscFunctionBegin; 10 if (cStart) *cStart = 0; 11 if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth]; 12 if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 13 if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 14 PetscFunctionReturn(0); 15 } 16 17 PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 18 { 19 PetscFunctionBegin; 20 if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth]; 21 if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 22 if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 23 if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 24 PetscFunctionReturn(0); 25 } 26 27 /* 28 Note that j and invj are non-square: 29 v0 + j x_face = x_cell 30 invj (x_cell - v0) = x_face 31 */ 32 PetscErrorCode CellRefinerGetAffineFaceTransforms_Internal(CellRefiner refiner, PetscInt *numFaces, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[], PetscReal *detj[]) 33 { 34 PetscReal *v = NULL, *j = NULL, *invj = NULL, *dj = NULL; 35 PetscInt cdim, fdim; 36 PetscErrorCode ierr; 37 38 PetscFunctionBegin; 39 switch (refiner) { 40 case REFINER_NOOP: break; 41 case REFINER_SIMPLEX_2D: 42 /* 43 2 44 |\ 45 | \ 46 | \ 47 | \ 48 | \ 49 | \ 50 | \ 51 2 1 52 | \ 53 | \ 54 | \ 55 0---0-------1 56 */ 57 cdim = 2; 58 fdim = 1; 59 if (numFaces) *numFaces = 3; 60 if (v0) { 61 ierr = PetscMalloc1(3*cdim, &v);CHKERRQ(ierr); 62 ierr = PetscMalloc1(3*cdim*fdim, &j);CHKERRQ(ierr); 63 ierr = PetscMalloc1(3*cdim*fdim, &invj);CHKERRQ(ierr); 64 ierr = PetscMalloc1(3, &dj);CHKERRQ(ierr); 65 /* 0 */ 66 v[0+0] = 0.0; v[0+1] = -1.0; 67 j[0+0] = 1.0; 68 j[0+1] = 0.0; 69 invj[0+0] = 1.0; invj[0+1] = 0.0; 70 dj[0] = 1.0; 71 /* 1 */ 72 v[2+0] = 0.0; v[2+1] = 0.0; 73 j[2+0] = -1.0; 74 j[2+1] = 1.0; 75 invj[2+0] = -0.5; invj[2+1] = 0.5; 76 dj[1] = 1.414213562373095; 77 /* 2 */ 78 v[4+0] = -1.0; v[4+1] = 0.0; 79 j[4+0] = 0.0; 80 j[4+1] = -1.0; 81 invj[4+0] = 0.0; invj[4+1] = -1.0; 82 dj[2] = 1.0; 83 } 84 break; 85 case REFINER_HEX_2D: 86 /* 87 3---------2---------2 88 | | 89 | | 90 | | 91 3 1 92 | | 93 | | 94 | | 95 0---------0---------1 96 */ 97 cdim = 2; 98 fdim = 1; 99 if (numFaces) *numFaces = 4; 100 if (v0) { 101 ierr = PetscMalloc1(4*cdim, &v);CHKERRQ(ierr); 102 ierr = PetscMalloc1(4*cdim*fdim, &j);CHKERRQ(ierr); 103 ierr = PetscMalloc1(4*cdim*fdim, &invj);CHKERRQ(ierr); 104 ierr = PetscMalloc1(4, &dj);CHKERRQ(ierr); 105 /* 0 */ 106 v[0+0] = 0.0; v[0+1] = -1.0; 107 j[0+0] = 1.0; 108 j[0+1] = 0.0; 109 invj[0+0] = 1.0; invj[0+1] = 0.0; 110 dj[0] = 1.0; 111 /* 1 */ 112 v[2+0] = 1.0; v[2+1] = 0.0; 113 j[2+0] = 0.0; 114 j[2+1] = 1.0; 115 invj[2+0] = 0.0; invj[2+1] = 1.0; 116 dj[1] = 1.0; 117 /* 2 */ 118 v[4+0] = 0.0; v[4+1] = 1.0; 119 j[4+0] = -1.0; 120 j[4+1] = 0.0; 121 invj[4+0] = -1.0; invj[4+1] = 0.0; 122 dj[2] = 1.0; 123 /* 3 */ 124 v[6+0] = -1.0; v[6+1] = 0.0; 125 j[6+0] = 0.0; 126 j[6+1] = -1.0; 127 invj[6+0] = 0.0; invj[6+1] = -1.0; 128 dj[3] = 1.0; 129 } 130 break; 131 default: 132 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 133 } 134 if (v0) {*v0 = v;} 135 else {ierr = PetscFree(v);CHKERRQ(ierr);} 136 if (jac) {*jac = j;} 137 else {ierr = PetscFree(j);CHKERRQ(ierr);} 138 if (invjac) {*invjac = invj;} 139 else {ierr = PetscFree(invj);CHKERRQ(ierr);} 140 if (invjac) {*invjac = invj;} 141 else {ierr = PetscFree(invj);CHKERRQ(ierr);} 142 if (detj) {*detj = dj;} 143 else {ierr = PetscFree(dj);CHKERRQ(ierr);} 144 PetscFunctionReturn(0); 145 } 146 147 /* Gets the affine map from the original cell to each subcell */ 148 PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 149 { 150 PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ; 151 PetscInt dim, s; 152 PetscErrorCode ierr; 153 154 PetscFunctionBegin; 155 switch (refiner) { 156 case REFINER_NOOP: break; 157 case REFINER_SIMPLEX_2D: 158 /* 159 2 160 |\ 161 | \ 162 | \ 163 | \ 164 | C \ 165 | \ 166 | \ 167 2---1---1 168 |\ D / \ 169 | 2 0 \ 170 |A \ / B \ 171 0---0-------1 172 */ 173 dim = 2; 174 if (numSubcells) *numSubcells = 4; 175 if (v0) { 176 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 177 /* A */ 178 v[0+0] = -1.0; v[0+1] = -1.0; 179 j[0+0] = 0.5; j[0+1] = 0.0; 180 j[0+2] = 0.0; j[0+3] = 0.5; 181 /* B */ 182 v[2+0] = 0.0; v[2+1] = -1.0; 183 j[4+0] = 0.5; j[4+1] = 0.0; 184 j[4+2] = 0.0; j[4+3] = 0.5; 185 /* C */ 186 v[4+0] = -1.0; v[4+1] = 0.0; 187 j[8+0] = 0.5; j[8+1] = 0.0; 188 j[8+2] = 0.0; j[8+3] = 0.5; 189 /* D */ 190 v[6+0] = 0.0; v[6+1] = -1.0; 191 j[12+0] = 0.0; j[12+1] = -0.5; 192 j[12+2] = 0.5; j[12+3] = 0.5; 193 for (s = 0; s < 4; ++s) { 194 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 195 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 196 } 197 } 198 break; 199 case REFINER_HEX_2D: 200 /* 201 3---------2---------2 202 | | | 203 | D 2 C | 204 | | | 205 3----3----0----1----1 206 | | | 207 | A 0 B | 208 | | | 209 0---------0---------1 210 */ 211 dim = 2; 212 if (numSubcells) *numSubcells = 4; 213 if (v0) { 214 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 215 /* A */ 216 v[0+0] = -1.0; v[0+1] = -1.0; 217 j[0+0] = 0.5; j[0+1] = 0.0; 218 j[0+2] = 0.0; j[0+3] = 0.5; 219 /* B */ 220 v[2+0] = 0.0; v[2+1] = -1.0; 221 j[4+0] = 0.5; j[4+1] = 0.0; 222 j[4+2] = 0.0; j[4+3] = 0.5; 223 /* C */ 224 v[4+0] = 0.0; v[4+1] = 0.0; 225 j[8+0] = 0.5; j[8+1] = 0.0; 226 j[8+2] = 0.0; j[8+3] = 0.5; 227 /* D */ 228 v[6+0] = -1.0; v[6+1] = 0.0; 229 j[12+0] = 0.5; j[12+1] = 0.0; 230 j[12+2] = 0.0; j[12+3] = 0.5; 231 for (s = 0; s < 4; ++s) { 232 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 233 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 234 } 235 } 236 break; 237 case REFINER_HEX_3D: 238 /* 239 Bottom (viewed from top) Top 240 1---------2---------2 7---------2---------6 241 | | | | | | 242 | B 2 C | | H 2 G | 243 | | | | | | 244 3----3----0----1----1 3----3----0----1----1 245 | | | | | | 246 | A 0 D | | E 0 F | 247 | | | | | | 248 0---------0---------3 4---------0---------5 249 */ 250 dim = 3; 251 if (numSubcells) *numSubcells = 8; 252 if (v0) { 253 ierr = PetscMalloc3(8*dim,&v,8*dim*dim,&j,8*dim*dim,&invj);CHKERRQ(ierr); 254 /* A */ 255 v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0; 256 j[0+0] = 0.5; j[0+1] = 0.0; j[0+2] = 0.0; 257 j[0+3] = 0.0; j[0+4] = 0.5; j[0+5] = 0.0; 258 j[0+6] = 0.0; j[0+7] = 0.0; j[0+8] = 0.5; 259 /* B */ 260 v[3+0] = -1.0; v[3+1] = 0.0; v[3+2] = -1.0; 261 j[9+0] = 0.5; j[9+1] = 0.0; j[9+2] = 0.0; 262 j[9+3] = 0.0; j[9+4] = 0.5; j[9+5] = 0.0; 263 j[9+6] = 0.0; j[9+7] = 0.0; j[9+8] = 0.5; 264 /* C */ 265 v[6+0] = 0.0; v[6+1] = 0.0; v[6+2] = -1.0; 266 j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0; 267 j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0; 268 j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5; 269 /* D */ 270 v[9+0] = 0.0; v[9+1] = -1.0; v[9+2] = -1.0; 271 j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0; 272 j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0; 273 j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5; 274 /* E */ 275 v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] = 0.0; 276 j[36+0] = 0.5; j[36+1] = 0.0; j[36+2] = 0.0; 277 j[36+3] = 0.0; j[36+4] = 0.5; j[36+5] = 0.0; 278 j[36+6] = 0.0; j[36+7] = 0.0; j[36+8] = 0.5; 279 /* F */ 280 v[15+0] = 0.0; v[15+1] = -1.0; v[15+2] = 0.0; 281 j[45+0] = 0.5; j[45+1] = 0.0; j[45+2] = 0.0; 282 j[45+3] = 0.0; j[45+4] = 0.5; j[45+5] = 0.0; 283 j[45+6] = 0.0; j[45+7] = 0.0; j[45+8] = 0.5; 284 /* G */ 285 v[18+0] = 0.0; v[18+1] = 0.0; v[18+2] = 0.0; 286 j[54+0] = 0.5; j[54+1] = 0.0; j[54+2] = 0.0; 287 j[54+3] = 0.0; j[54+4] = 0.5; j[54+5] = 0.0; 288 j[54+6] = 0.0; j[54+7] = 0.0; j[54+8] = 0.5; 289 /* H */ 290 v[21+0] = -1.0; v[21+1] = 0.0; v[21+2] = 0.0; 291 j[63+0] = 0.5; j[63+1] = 0.0; j[63+2] = 0.0; 292 j[63+3] = 0.0; j[63+4] = 0.5; j[63+5] = 0.0; 293 j[63+6] = 0.0; j[63+7] = 0.0; j[63+8] = 0.5; 294 for (s = 0; s < 8; ++s) { 295 DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]); 296 DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 297 } 298 } 299 break; 300 default: 301 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 302 } 303 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 304 PetscFunctionReturn(0); 305 } 306 307 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 308 { 309 PetscErrorCode ierr; 310 311 PetscFunctionBegin; 312 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 313 PetscFunctionReturn(0); 314 } 315 316 /* Should this be here or in the DualSpace somehow? */ 317 PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside) 318 { 319 PetscReal sum = 0.0; 320 PetscInt d; 321 322 PetscFunctionBegin; 323 *inside = PETSC_TRUE; 324 switch (refiner) { 325 case REFINER_NOOP: break; 326 case REFINER_SIMPLEX_2D: 327 for (d = 0; d < 2; ++d) { 328 if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 329 sum += point[d]; 330 } 331 if (sum > 1.0e-10) {*inside = PETSC_FALSE; break;} 332 break; 333 case REFINER_HEX_2D: 334 for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*inside = PETSC_FALSE; break;} 335 break; 336 case REFINER_HEX_3D: 337 for (d = 0; d < 3; d++) if (PetscAbsReal(point[d]) > 1 + PETSC_SMALL) {*inside = PETSC_FALSE; break;} 338 break; 339 default: 340 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 341 } 342 PetscFunctionReturn(0); 343 } 344 345 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 346 { 347 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 348 PetscErrorCode ierr; 349 350 PetscFunctionBegin; 351 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 352 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 353 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 354 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 355 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 356 switch (refiner) { 357 case REFINER_NOOP: 358 break; 359 case REFINER_SIMPLEX_1D: 360 depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */ 361 depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */ 362 break; 363 case REFINER_SIMPLEX_2D: 364 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 365 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 366 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 367 break; 368 case REFINER_HYBRID_SIMPLEX_2D: 369 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 370 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 371 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 372 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 */ 373 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, hybrid cells split into 2 cells */ 374 break; 375 case REFINER_SIMPLEX_TO_HEX_2D: 376 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 377 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 378 depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */ 379 break; 380 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 381 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 382 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 383 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 */ 384 depthSize[2] = 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every cell split into 3 cells, hybrid cells split in 4 */ 385 break; 386 case REFINER_HEX_2D: 387 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 388 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 389 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 390 break; 391 case REFINER_HYBRID_HEX_2D: 392 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 393 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 394 /* Quadrilateral */ 395 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 396 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 397 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 398 /* Segment Prisms */ 399 depthSize[0] += 0; /* No hybrid vertices */ 400 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 401 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 402 break; 403 case REFINER_SIMPLEX_3D: 404 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 405 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 */ 406 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 407 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 408 break; 409 case REFINER_HYBRID_SIMPLEX_3D: 410 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 411 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 412 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 413 /* Tetrahedra */ 414 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 415 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 */ 416 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 417 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 418 /* Triangular Prisms */ 419 depthSize[0] += 0; /* No hybrid vertices */ 420 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 421 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 422 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 423 break; 424 case REFINER_SIMPLEX_TO_HEX_3D: 425 depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */ 426 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 */ 427 depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */ 428 depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 429 break; 430 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 431 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 432 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 433 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 434 /* Tetrahedra */ 435 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every interior edge, face and cell */ 436 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 */ 437 depthSize[2] = 3*(fMax - fStart) + 6*(cMax - cStart); /* Every interior face split into 3 faces, 6 faces added for each interior cell */ 438 depthSize[3] = 4*(cMax - cStart); /* Every interior cell split into 8 cells */ 439 /* Triangular Prisms */ 440 depthSize[0] += 0; /* No hybrid vertices */ 441 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and cell */ 442 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 443 depthSize[3] += 3*(cEnd - cMax); /* Every hybrid cell split into 3 cells */ 444 break; 445 case REFINER_HEX_3D: 446 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 447 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 */ 448 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 449 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 450 break; 451 case REFINER_HYBRID_HEX_3D: 452 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 453 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 454 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 455 /* Hexahedra */ 456 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 457 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 */ 458 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 459 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 460 /* Quadrilateral Prisms */ 461 depthSize[0] += 0; /* No hybrid vertices */ 462 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 463 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 464 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 465 break; 466 default: 467 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 468 } 469 PetscFunctionReturn(0); 470 } 471 472 /* Return triangle edge for orientation o, if it is r for o == 0 */ 473 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 474 return (o < 0 ? 2-(o+r) : o+r)%3; 475 } 476 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 477 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 478 } 479 480 /* Return triangle subface for orientation o, if it is r for o == 0 */ 481 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 482 return (o < 0 ? 3-(o+r) : o+r)%3; 483 } 484 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 485 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 486 } 487 488 /* Return the interior edge number connecting the midpoints of the triangle edges r 489 and r+1 in the transitive closure for triangle orientation o */ 490 PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) { 491 return (o < 0 ? 1-(o+r) : o+r)%3; 492 } 493 PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) { 494 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 495 } 496 497 /* Return the interior edge number connecting the midpoint of the triangle edge r 498 (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */ 499 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) { 500 return (o < 0 ? 2-(o+r) : o+r)%3; 501 } 502 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) { 503 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 504 } 505 506 /* Return quad edge for orientation o, if it is r for o == 0 */ 507 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 508 return (o < 0 ? 3-(o+r) : o+r)%4; 509 } 510 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 511 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 512 } 513 514 /* Return quad subface for orientation o, if it is r for o == 0 */ 515 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 516 return (o < 0 ? 4-(o+r) : o+r)%4; 517 } 518 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 519 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 520 } 521 522 static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd) 523 { 524 IS cIS; 525 PetscErrorCode ierr; 526 527 PetscFunctionBegin; 528 ierr = ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);CHKERRQ(ierr); 529 ierr = DMLabelSetStratumIS(label, value, cIS);CHKERRQ(ierr); 530 ierr = ISDestroy(&cIS);CHKERRQ(ierr); 531 PetscFunctionReturn(0); 532 } 533 534 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 535 { 536 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; 537 DMLabel depthLabel; 538 PetscErrorCode ierr; 539 540 PetscFunctionBegin; 541 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 542 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 543 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 544 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 545 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 546 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 547 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 548 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 549 ierr = DMCreateLabel(rdm,"depth");CHKERRQ(ierr); 550 ierr = DMPlexGetDepthLabel(rdm,&depthLabel);CHKERRQ(ierr); 551 ierr = DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);CHKERRQ(ierr); 552 if (depth > 2) ierr = DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);CHKERRQ(ierr); 553 if (depth > 1) ierr = DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);CHKERRQ(ierr); 554 if (depth > 0) ierr = DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);CHKERRQ(ierr); 555 { 556 DM_Plex *plex = (DM_Plex *) rdm->data; 557 ierr = PetscObjectStateGet((PetscObject) depthLabel, &plex->depthState);CHKERRQ(ierr); 558 } 559 if (!refiner) PetscFunctionReturn(0); 560 switch (refiner) { 561 case REFINER_SIMPLEX_1D: 562 /* All cells have 2 vertices */ 563 for (c = cStart; c < cEnd; ++c) { 564 for (r = 0; r < 2; ++r) { 565 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 566 567 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 568 } 569 } 570 /* Old vertices have identical supports */ 571 for (v = vStart; v < vEnd; ++v) { 572 const PetscInt newp = vStartNew + (v - vStart); 573 PetscInt size; 574 575 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 576 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 577 } 578 /* Cell vertices have support 2 */ 579 for (c = cStart; c < cEnd; ++c) { 580 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 581 582 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 583 } 584 break; 585 case REFINER_SIMPLEX_2D: 586 /* All cells have 3 faces */ 587 for (c = cStart; c < cEnd; ++c) { 588 for (r = 0; r < 4; ++r) { 589 const PetscInt newp = (c - cStart)*4 + r; 590 591 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 592 } 593 } 594 /* Split faces have 2 vertices and the same cells as the parent */ 595 for (f = fStart; f < fEnd; ++f) { 596 for (r = 0; r < 2; ++r) { 597 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 598 PetscInt size; 599 600 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 601 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 602 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 603 } 604 } 605 /* Interior faces have 2 vertices and 2 cells */ 606 for (c = cStart; c < cEnd; ++c) { 607 for (r = 0; r < 3; ++r) { 608 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 609 610 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 611 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 612 } 613 } 614 /* Old vertices have identical supports */ 615 for (v = vStart; v < vEnd; ++v) { 616 const PetscInt newp = vStartNew + (v - vStart); 617 PetscInt size; 618 619 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 620 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 621 } 622 /* Face vertices have 2 + cells*2 supports */ 623 for (f = fStart; f < fEnd; ++f) { 624 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 625 PetscInt size; 626 627 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 628 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 629 } 630 break; 631 case REFINER_SIMPLEX_TO_HEX_2D: 632 /* All cells have 4 faces */ 633 for (c = cStart; c < cEnd; ++c) { 634 for (r = 0; r < 3; ++r) { 635 const PetscInt newp = (c - cStart)*3 + r; 636 637 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 638 } 639 } 640 /* Split faces have 2 vertices and the same cells as the parent */ 641 for (f = fStart; f < fEnd; ++f) { 642 for (r = 0; r < 2; ++r) { 643 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 644 PetscInt size; 645 646 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 647 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 648 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 649 } 650 } 651 /* Interior faces have 2 vertices and 2 cells */ 652 for (c = cStart; c < cEnd; ++c) { 653 for (r = 0; r < 3; ++r) { 654 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 655 656 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 657 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 658 } 659 } 660 /* Old vertices have identical supports */ 661 for (v = vStart; v < vEnd; ++v) { 662 const PetscInt newp = vStartNew + (v - vStart); 663 PetscInt size; 664 665 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 666 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 667 } 668 /* Split-face vertices have cells + 2 supports */ 669 for (f = fStart; f < fEnd; ++f) { 670 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 671 PetscInt size; 672 673 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 674 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 675 } 676 /* Interior vertices have 3 supports */ 677 for (c = cStart; c < cEnd; ++c) { 678 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 679 680 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 681 } 682 break; 683 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 684 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 685 /* the mesh is no longer hybrid */ 686 cMax = PetscMin(cEnd, cMax); 687 /* All cells have 4 faces */ 688 for (c = cStart; c < cMax; ++c) { 689 for (r = 0; r < 3; ++r) { 690 const PetscInt newp = (c - cStart)*3 + r; 691 692 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 693 } 694 } 695 for (c = cMax; c < cEnd; ++c) { 696 for (r = 0; r < 4; ++r) { 697 const PetscInt newp = (cMax - cStart)*3 + (c - cMax)*4 + r; 698 699 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 700 } 701 } 702 /* Split faces have 2 vertices and the same cells as the parent */ 703 for (f = fStart; f < fEnd; ++f) { 704 for (r = 0; r < 2; ++r) { 705 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 706 PetscInt size; 707 708 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 709 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 710 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 711 } 712 } 713 /* Interior faces have 2 vertices and 2 cells */ 714 for (c = cStart; c < cMax; ++c) { 715 for (r = 0; r < 3; ++r) { 716 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 717 718 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 719 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 720 } 721 } 722 /* Hybrid interior faces have 2 vertices and 2 cells */ 723 for (c = cMax; c < cEnd; ++c) { 724 for (r = 0; r < 4; ++r) { 725 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 726 727 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 728 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 729 } 730 } 731 /* Old vertices have identical supports */ 732 for (v = vStart; v < vEnd; ++v) { 733 const PetscInt newp = vStartNew + (v - vStart); 734 PetscInt size; 735 736 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 737 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 738 } 739 /* Split-face vertices have cells + 2 supports */ 740 for (f = fStart; f < fEnd; ++f) { 741 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 742 PetscInt size; 743 744 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 745 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 746 } 747 /* Interior vertices have 3 supports */ 748 for (c = cStart; c < cMax; ++c) { 749 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 750 751 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 752 } 753 /* Hybrid interior vertices have 4 supports */ 754 for (c = cMax; c < cEnd; ++c) { 755 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 756 757 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 758 } 759 break; 760 case REFINER_HEX_2D: 761 /* All cells have 4 faces */ 762 for (c = cStart; c < cEnd; ++c) { 763 for (r = 0; r < 4; ++r) { 764 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 765 766 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 767 } 768 } 769 /* Split faces have 2 vertices and the same cells as the parent */ 770 for (f = fStart; f < fEnd; ++f) { 771 for (r = 0; r < 2; ++r) { 772 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 773 PetscInt size; 774 775 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 776 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 777 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 778 } 779 } 780 /* Interior faces have 2 vertices and 2 cells */ 781 for (c = cStart; c < cEnd; ++c) { 782 for (r = 0; r < 4; ++r) { 783 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 784 785 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 786 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 787 } 788 } 789 /* Old vertices have identical supports */ 790 for (v = vStart; v < vEnd; ++v) { 791 const PetscInt newp = vStartNew + (v - vStart); 792 PetscInt size; 793 794 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 795 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 796 } 797 /* Face vertices have 2 + cells supports */ 798 for (f = fStart; f < fEnd; ++f) { 799 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 800 PetscInt size; 801 802 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 803 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 804 } 805 /* Cell vertices have 4 supports */ 806 for (c = cStart; c < cEnd; ++c) { 807 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 808 809 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 810 } 811 break; 812 case REFINER_HYBRID_SIMPLEX_2D: 813 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 814 cMax = PetscMin(cEnd, cMax); 815 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 816 fMax = PetscMin(fEnd, fMax); 817 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 818 /* Interior cells have 3 faces */ 819 for (c = cStart; c < cMax; ++c) { 820 for (r = 0; r < 4; ++r) { 821 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 822 823 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 824 } 825 } 826 /* Hybrid cells have 4 faces */ 827 for (c = cMax; c < cEnd; ++c) { 828 for (r = 0; r < 2; ++r) { 829 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 830 831 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 832 } 833 } 834 /* Interior split faces have 2 vertices and the same cells as the parent */ 835 for (f = fStart; f < fMax; ++f) { 836 for (r = 0; r < 2; ++r) { 837 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 838 PetscInt size; 839 840 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 841 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 842 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 843 } 844 } 845 /* Interior cell faces have 2 vertices and 2 cells */ 846 for (c = cStart; c < cMax; ++c) { 847 for (r = 0; r < 3; ++r) { 848 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 849 850 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 851 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 852 } 853 } 854 /* Hybrid faces have 2 vertices and the same cells */ 855 for (f = fMax; f < fEnd; ++f) { 856 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 857 PetscInt size; 858 859 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 860 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 861 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 862 } 863 /* Hybrid cell faces have 2 vertices and 2 cells */ 864 for (c = cMax; c < cEnd; ++c) { 865 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 866 867 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 868 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 869 } 870 /* Old vertices have identical supports */ 871 for (v = vStart; v < vEnd; ++v) { 872 const PetscInt newp = vStartNew + (v - vStart); 873 PetscInt size; 874 875 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 876 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 877 } 878 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 879 for (f = fStart; f < fMax; ++f) { 880 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 881 const PetscInt *support; 882 PetscInt size, newSize = 2, s; 883 884 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 885 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 886 for (s = 0; s < size; ++s) { 887 if (support[s] >= cMax) newSize += 1; 888 else newSize += 2; 889 } 890 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 891 } 892 break; 893 case REFINER_HYBRID_HEX_2D: 894 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 895 cMax = PetscMin(cEnd, cMax); 896 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 897 fMax = PetscMin(fEnd, fMax); 898 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 899 /* Interior cells have 4 faces */ 900 for (c = cStart; c < cMax; ++c) { 901 for (r = 0; r < 4; ++r) { 902 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 903 904 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 905 } 906 } 907 /* Hybrid cells have 4 faces */ 908 for (c = cMax; c < cEnd; ++c) { 909 for (r = 0; r < 2; ++r) { 910 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 911 912 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 913 } 914 } 915 /* Interior split faces have 2 vertices and the same cells as the parent */ 916 for (f = fStart; f < fMax; ++f) { 917 for (r = 0; r < 2; ++r) { 918 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 919 PetscInt size; 920 921 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 922 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 923 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 924 } 925 } 926 /* Interior cell faces have 2 vertices and 2 cells */ 927 for (c = cStart; c < cMax; ++c) { 928 for (r = 0; r < 4; ++r) { 929 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 930 931 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 932 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 933 } 934 } 935 /* Hybrid faces have 2 vertices and the same cells */ 936 for (f = fMax; f < fEnd; ++f) { 937 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 938 PetscInt size; 939 940 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 941 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 942 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 943 } 944 /* Hybrid cell faces have 2 vertices and 2 cells */ 945 for (c = cMax; c < cEnd; ++c) { 946 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 947 948 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 949 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 950 } 951 /* Old vertices have identical supports */ 952 for (v = vStart; v < vEnd; ++v) { 953 const PetscInt newp = vStartNew + (v - vStart); 954 PetscInt size; 955 956 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 957 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 958 } 959 /* Face vertices have 2 + cells supports */ 960 for (f = fStart; f < fMax; ++f) { 961 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 962 PetscInt size; 963 964 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 965 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 966 } 967 /* Cell vertices have 4 supports */ 968 for (c = cStart; c < cMax; ++c) { 969 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 970 971 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 972 } 973 break; 974 case REFINER_SIMPLEX_3D: 975 /* All cells have 4 faces */ 976 for (c = cStart; c < cEnd; ++c) { 977 for (r = 0; r < 8; ++r) { 978 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 979 980 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 981 } 982 } 983 /* Split faces have 3 edges and the same cells as the parent */ 984 for (f = fStart; f < fEnd; ++f) { 985 for (r = 0; r < 4; ++r) { 986 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 987 PetscInt size; 988 989 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 990 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 991 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 992 } 993 } 994 /* Interior cell faces have 3 edges and 2 cells */ 995 for (c = cStart; c < cEnd; ++c) { 996 for (r = 0; r < 8; ++r) { 997 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 998 999 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 1000 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1001 } 1002 } 1003 /* Split edges have 2 vertices and the same faces */ 1004 for (e = eStart; e < eEnd; ++e) { 1005 for (r = 0; r < 2; ++r) { 1006 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1007 PetscInt size; 1008 1009 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1010 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1011 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1012 } 1013 } 1014 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 1015 for (f = fStart; f < fEnd; ++f) { 1016 for (r = 0; r < 3; ++r) { 1017 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1018 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 1019 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 1020 1021 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1022 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1023 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1024 for (s = 0; s < supportSize; ++s) { 1025 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1026 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1027 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1028 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1029 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 1030 er = GetTriMidEdgeInverse_Static(ornt[c], r); 1031 if (er == eint[c]) { 1032 intFaces += 1; 1033 } else { 1034 intFaces += 2; 1035 } 1036 } 1037 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 1038 } 1039 } 1040 /* Interior cell edges have 2 vertices and 4 faces */ 1041 for (c = cStart; c < cEnd; ++c) { 1042 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1043 1044 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1045 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1046 } 1047 /* Old vertices have identical supports */ 1048 for (v = vStart; v < vEnd; ++v) { 1049 const PetscInt newp = vStartNew + (v - vStart); 1050 PetscInt size; 1051 1052 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1053 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1054 } 1055 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 1056 for (e = eStart; e < eEnd; ++e) { 1057 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1058 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 1059 1060 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1061 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1062 for (s = 0; s < starSize*2; s += 2) { 1063 const PetscInt *cone, *ornt; 1064 PetscInt e01, e23; 1065 1066 if ((star[s] >= cStart) && (star[s] < cEnd)) { 1067 /* Check edge 0-1 */ 1068 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1069 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1070 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1071 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1072 /* Check edge 2-3 */ 1073 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1074 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1075 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1076 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1077 if ((e01 == e) || (e23 == e)) ++cellSize; 1078 } 1079 } 1080 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1081 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 1082 } 1083 break; 1084 case REFINER_HYBRID_SIMPLEX_3D: 1085 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 1086 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1087 /* Interior cells have 4 faces */ 1088 for (c = cStart; c < cMax; ++c) { 1089 for (r = 0; r < 8; ++r) { 1090 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1091 1092 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1093 } 1094 } 1095 /* Hybrid cells have 5 faces */ 1096 for (c = cMax; c < cEnd; ++c) { 1097 for (r = 0; r < 4; ++r) { 1098 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1099 1100 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 1101 } 1102 } 1103 /* Interior split faces have 3 edges and the same cells as the parent */ 1104 for (f = fStart; f < fMax; ++f) { 1105 for (r = 0; r < 4; ++r) { 1106 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1107 PetscInt size; 1108 1109 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 1110 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1111 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1112 } 1113 } 1114 /* Interior cell faces have 3 edges and 2 cells */ 1115 for (c = cStart; c < cMax; ++c) { 1116 for (r = 0; r < 8; ++r) { 1117 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 1118 1119 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 1120 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1121 } 1122 } 1123 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1124 for (f = fMax; f < fEnd; ++f) { 1125 for (r = 0; r < 2; ++r) { 1126 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 1127 PetscInt size; 1128 1129 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1130 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1131 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1132 } 1133 } 1134 /* Hybrid cells faces have 4 edges and 2 cells */ 1135 for (c = cMax; c < cEnd; ++c) { 1136 for (r = 0; r < 3; ++r) { 1137 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1138 1139 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1140 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1141 } 1142 } 1143 /* Interior split edges have 2 vertices and the same faces */ 1144 for (e = eStart; e < eMax; ++e) { 1145 for (r = 0; r < 2; ++r) { 1146 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1147 PetscInt size; 1148 1149 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1150 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1151 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1152 } 1153 } 1154 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 1155 for (f = fStart; f < fMax; ++f) { 1156 for (r = 0; r < 3; ++r) { 1157 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1158 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 1159 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 1160 1161 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1162 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1163 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1164 for (s = 0; s < supportSize; ++s) { 1165 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1166 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1167 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1168 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1169 if (support[s] < cMax) { 1170 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 1171 er = GetTriMidEdgeInverse_Static(ornt[c], r); 1172 if (er == eint[c]) { 1173 intFaces += 1; 1174 } else { 1175 intFaces += 2; 1176 } 1177 } else { 1178 intFaces += 1; 1179 } 1180 } 1181 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 1182 } 1183 } 1184 /* Interior cell edges have 2 vertices and 4 faces */ 1185 for (c = cStart; c < cMax; ++c) { 1186 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 1187 1188 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1189 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1190 } 1191 /* Hybrid edges have 2 vertices and the same faces */ 1192 for (e = eMax; e < eEnd; ++e) { 1193 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 1194 PetscInt size; 1195 1196 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1197 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1198 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1199 } 1200 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 1201 for (f = fMax; f < fEnd; ++f) { 1202 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 1203 PetscInt size; 1204 1205 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1206 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1207 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 1208 } 1209 /* Interior vertices have identical supports */ 1210 for (v = vStart; v < vEnd; ++v) { 1211 const PetscInt newp = vStartNew + (v - vStart); 1212 PetscInt size; 1213 1214 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1215 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1216 } 1217 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 1218 for (e = eStart; e < eMax; ++e) { 1219 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1220 const PetscInt *support; 1221 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 1222 1223 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1224 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1225 for (s = 0; s < size; ++s) { 1226 if (support[s] < fMax) faceSize += 2; 1227 else faceSize += 1; 1228 } 1229 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1230 for (s = 0; s < starSize*2; s += 2) { 1231 const PetscInt *cone, *ornt; 1232 PetscInt e01, e23; 1233 1234 if ((star[s] >= cStart) && (star[s] < cMax)) { 1235 /* Check edge 0-1 */ 1236 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1237 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1238 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1239 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1240 /* Check edge 2-3 */ 1241 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1242 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1243 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1244 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1245 if ((e01 == e) || (e23 == e)) ++cellSize; 1246 } 1247 } 1248 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1249 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 1250 } 1251 break; 1252 case REFINER_SIMPLEX_TO_HEX_3D: 1253 /* All cells have 6 faces */ 1254 for (c = cStart; c < cEnd; ++c) { 1255 for (r = 0; r < 4; ++r) { 1256 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1257 1258 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1259 } 1260 } 1261 /* Split faces have 4 edges and the same cells as the parent */ 1262 for (f = fStart; f < fEnd; ++f) { 1263 for (r = 0; r < 3; ++r) { 1264 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1265 PetscInt size; 1266 1267 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1268 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1269 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1270 } 1271 } 1272 /* Interior cell faces have 4 edges and 2 cells */ 1273 for (c = cStart; c < cEnd; ++c) { 1274 for (r = 0; r < 6; ++r) { 1275 const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r; 1276 1277 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1278 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1279 } 1280 } 1281 /* Split edges have 2 vertices and the same faces */ 1282 for (e = eStart; e < eEnd; ++e) { 1283 for (r = 0; r < 2; ++r) { 1284 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1285 PetscInt size; 1286 1287 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1288 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1289 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1290 } 1291 } 1292 /* Face edges have 2 vertices and 2 + cell faces supports */ 1293 for (f = fStart; f < fEnd; ++f) { 1294 for (r = 0; r < 3; ++r) { 1295 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1296 PetscInt size; 1297 1298 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1299 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1300 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1301 } 1302 } 1303 /* Interior cell edges have 2 vertices and 3 faces */ 1304 for (c = cStart; c < cEnd; ++c) { 1305 for (r = 0; r < 4; ++r) { 1306 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 1307 1308 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1309 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1310 } 1311 } 1312 /* Old vertices have identical supports */ 1313 for (v = vStart; v < vEnd; ++v) { 1314 const PetscInt newp = vStartNew + (v - vStart); 1315 PetscInt size; 1316 1317 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1318 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1319 } 1320 /* Edge vertices have 2 + faces supports */ 1321 for (e = eStart; e < eEnd; ++e) { 1322 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1323 PetscInt size; 1324 1325 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1326 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1327 } 1328 /* Face vertices have 3 + cells supports */ 1329 for (f = fStart; f < fEnd; ++f) { 1330 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 1331 PetscInt size; 1332 1333 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1334 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1335 } 1336 /* Interior cell vertices have 4 supports */ 1337 for (c = cStart; c < cEnd; ++c) { 1338 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart; 1339 1340 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1341 } 1342 break; 1343 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 1344 /* the mesh is no longer hybrid */ 1345 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1346 cMax = PetscMin(cEnd, cMax); 1347 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1348 fMax = PetscMin(fEnd, fMax); 1349 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 1350 eMax = PetscMin(eEnd, eMax); 1351 /* All cells have 6 faces */ 1352 for (c = cStart; c < cMax; ++c) { 1353 for (r = 0; r < 4; ++r) { 1354 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1355 1356 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1357 } 1358 } 1359 for (c = cMax; c < cEnd; ++c) { 1360 for (r = 0; r < 3; ++r) { 1361 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + r; 1362 1363 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1364 } 1365 } 1366 /* Interior split faces have 4 edges and the same cells as the parent */ 1367 for (f = fStart; f < fMax; ++f) { 1368 for (r = 0; r < 3; ++r) { 1369 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1370 PetscInt size; 1371 1372 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1373 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1374 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1375 } 1376 } 1377 /* Interior cell faces have 4 edges and 2 cells */ 1378 for (c = cStart; c < cMax; ++c) { 1379 for (r = 0; r < 6; ++r) { 1380 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + r; 1381 1382 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1383 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1384 } 1385 } 1386 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1387 for (f = fMax; f < fEnd; ++f) { 1388 for (r = 0; r < 2; ++r) { 1389 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2 + r; 1390 PetscInt size; 1391 1392 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1393 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1394 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1395 } 1396 } 1397 /* Hybrid cell faces have 4 edges and 2 cells */ 1398 for (c = cMax; c < cEnd; ++c) { 1399 for (r = 0; r < 3; ++r) { 1400 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1401 1402 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1403 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1404 } 1405 } 1406 /* Interior split edges have 2 vertices and the same faces */ 1407 for (e = eStart; e < eMax; ++e) { 1408 for (r = 0; r < 2; ++r) { 1409 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1410 PetscInt size; 1411 1412 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1413 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1414 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1415 } 1416 } 1417 /* Interior face edges have 2 vertices and 2 + cell faces supports */ 1418 for (f = fStart; f < fMax; ++f) { 1419 for (r = 0; r < 3; ++r) { 1420 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1421 PetscInt size; 1422 1423 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1424 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1425 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1426 } 1427 } 1428 /* Interior cell edges have 2 vertices and 3 faces */ 1429 for (c = cStart; c < cMax; ++c) { 1430 for (r = 0; r < 4; ++r) { 1431 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 1432 1433 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1434 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1435 } 1436 } 1437 /* Hybrid edges have 2 vertices and the same faces */ 1438 for (e = eMax; e < eEnd; ++e) { 1439 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 1440 PetscInt size; 1441 1442 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1443 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1444 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1445 } 1446 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1447 for (f = fMax; f < fEnd; ++f) { 1448 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 1449 PetscInt size; 1450 1451 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1452 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1453 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1454 } 1455 /* Hybrid cell edges have 2 vertices and 3 faces */ 1456 for (c = cMax; c < cEnd; ++c) { 1457 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1458 1459 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1460 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1461 } 1462 /* Old vertices have identical supports */ 1463 for (v = vStart; v < vEnd; ++v) { 1464 const PetscInt newp = vStartNew + (v - vStart); 1465 PetscInt size; 1466 1467 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1468 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1469 } 1470 /* Interior edge vertices have 2 + faces supports */ 1471 for (e = eStart; e < eMax; ++e) { 1472 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1473 PetscInt size; 1474 1475 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1476 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1477 } 1478 /* Interior face vertices have 3 + cells supports */ 1479 for (f = fStart; f < fMax; ++f) { 1480 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 1481 PetscInt size; 1482 1483 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1484 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1485 } 1486 /* Interior cell vertices have 4 supports */ 1487 for (c = cStart; c < cMax; ++c) { 1488 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 1489 1490 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1491 } 1492 break; 1493 case REFINER_HEX_3D: 1494 /* All cells have 6 faces */ 1495 for (c = cStart; c < cEnd; ++c) { 1496 for (r = 0; r < 8; ++r) { 1497 const PetscInt newp = (c - cStart)*8 + r; 1498 1499 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1500 } 1501 } 1502 /* Split faces have 4 edges and the same cells as the parent */ 1503 for (f = fStart; f < fEnd; ++f) { 1504 for (r = 0; r < 4; ++r) { 1505 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1506 PetscInt size; 1507 1508 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1509 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1510 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1511 } 1512 } 1513 /* Interior faces have 4 edges and 2 cells */ 1514 for (c = cStart; c < cEnd; ++c) { 1515 for (r = 0; r < 12; ++r) { 1516 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 1517 1518 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1519 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1520 } 1521 } 1522 /* Split edges have 2 vertices and the same faces as the parent */ 1523 for (e = eStart; e < eEnd; ++e) { 1524 for (r = 0; r < 2; ++r) { 1525 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1526 PetscInt size; 1527 1528 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1529 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1530 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1531 } 1532 } 1533 /* Face edges have 2 vertices and 2+cells faces */ 1534 for (f = fStart; f < fEnd; ++f) { 1535 for (r = 0; r < 4; ++r) { 1536 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 1537 PetscInt size; 1538 1539 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1540 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1541 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1542 } 1543 } 1544 /* Cell edges have 2 vertices and 4 faces */ 1545 for (c = cStart; c < cEnd; ++c) { 1546 for (r = 0; r < 6; ++r) { 1547 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 1548 1549 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1550 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1551 } 1552 } 1553 /* Old vertices have identical supports */ 1554 for (v = vStart; v < vEnd; ++v) { 1555 const PetscInt newp = vStartNew + (v - vStart); 1556 PetscInt size; 1557 1558 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1559 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1560 } 1561 /* Edge vertices have 2 + faces supports */ 1562 for (e = eStart; e < eEnd; ++e) { 1563 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1564 PetscInt size; 1565 1566 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1567 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1568 } 1569 /* Face vertices have 4 + cells supports */ 1570 for (f = fStart; f < fEnd; ++f) { 1571 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 1572 PetscInt size; 1573 1574 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1575 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1576 } 1577 /* Cell vertices have 6 supports */ 1578 for (c = cStart; c < cEnd; ++c) { 1579 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 1580 1581 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1582 } 1583 break; 1584 case REFINER_HYBRID_HEX_3D: 1585 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 1586 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1587 /* Interior cells have 6 faces */ 1588 for (c = cStart; c < cMax; ++c) { 1589 for (r = 0; r < 8; ++r) { 1590 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1591 1592 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1593 } 1594 } 1595 /* Hybrid cells have 6 faces */ 1596 for (c = cMax; c < cEnd; ++c) { 1597 for (r = 0; r < 4; ++r) { 1598 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1599 1600 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1601 } 1602 } 1603 /* Interior split faces have 4 edges and the same cells as the parent */ 1604 for (f = fStart; f < fMax; ++f) { 1605 for (r = 0; r < 4; ++r) { 1606 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1607 PetscInt size; 1608 1609 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1610 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1611 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1612 } 1613 } 1614 /* Interior cell faces have 4 edges and 2 cells */ 1615 for (c = cStart; c < cMax; ++c) { 1616 for (r = 0; r < 12; ++r) { 1617 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1618 1619 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1620 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1621 } 1622 } 1623 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1624 for (f = fMax; f < fEnd; ++f) { 1625 for (r = 0; r < 2; ++r) { 1626 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1627 PetscInt size; 1628 1629 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1630 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1631 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1632 } 1633 } 1634 /* Hybrid cells faces have 4 edges and 2 cells */ 1635 for (c = cMax; c < cEnd; ++c) { 1636 for (r = 0; r < 4; ++r) { 1637 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1638 1639 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1640 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1641 } 1642 } 1643 /* Interior split edges have 2 vertices and the same faces as the parent */ 1644 for (e = eStart; e < eMax; ++e) { 1645 for (r = 0; r < 2; ++r) { 1646 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1647 PetscInt size; 1648 1649 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1650 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1651 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1652 } 1653 } 1654 /* Interior face edges have 2 vertices and 2+cells faces */ 1655 for (f = fStart; f < fMax; ++f) { 1656 for (r = 0; r < 4; ++r) { 1657 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1658 PetscInt size; 1659 1660 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1661 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1662 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1663 } 1664 } 1665 /* Interior cell edges have 2 vertices and 4 faces */ 1666 for (c = cStart; c < cMax; ++c) { 1667 for (r = 0; r < 6; ++r) { 1668 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1669 1670 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1671 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1672 } 1673 } 1674 /* Hybrid edges have 2 vertices and the same faces */ 1675 for (e = eMax; e < eEnd; ++e) { 1676 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1677 PetscInt size; 1678 1679 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1680 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1681 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1682 } 1683 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1684 for (f = fMax; f < fEnd; ++f) { 1685 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1686 PetscInt size; 1687 1688 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1689 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1690 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1691 } 1692 /* Hybrid cell edges have 2 vertices and 4 faces */ 1693 for (c = cMax; c < cEnd; ++c) { 1694 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1695 1696 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1697 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1698 } 1699 /* Interior vertices have identical supports */ 1700 for (v = vStart; v < vEnd; ++v) { 1701 const PetscInt newp = vStartNew + (v - vStart); 1702 PetscInt size; 1703 1704 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1705 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1706 } 1707 /* Interior edge vertices have 2 + faces supports */ 1708 for (e = eStart; e < eMax; ++e) { 1709 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1710 PetscInt size; 1711 1712 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1713 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1714 } 1715 /* Interior face vertices have 4 + cells supports */ 1716 for (f = fStart; f < fMax; ++f) { 1717 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1718 PetscInt size; 1719 1720 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1721 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1722 } 1723 /* Interior cell vertices have 6 supports */ 1724 for (c = cStart; c < cMax; ++c) { 1725 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1726 1727 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1728 } 1729 break; 1730 default: 1731 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 1732 } 1733 PetscFunctionReturn(0); 1734 } 1735 1736 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1737 { 1738 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1739 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1740 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1741 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r; 1742 #if defined(PETSC_USE_DEBUG) 1743 PetscInt p; 1744 #endif 1745 PetscErrorCode ierr; 1746 1747 PetscFunctionBegin; 1748 if (!refiner) PetscFunctionReturn(0); 1749 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1750 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1751 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1752 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1753 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1754 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1755 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1756 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1757 switch (refiner) { 1758 case REFINER_SIMPLEX_1D: 1759 /* Max support size of refined mesh is 2 */ 1760 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1761 /* All cells have 2 vertices */ 1762 for (c = cStart; c < cEnd; ++c) { 1763 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1764 1765 for (r = 0; r < 2; ++r) { 1766 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1767 const PetscInt *cone; 1768 PetscInt coneNew[2]; 1769 1770 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1771 coneNew[0] = vStartNew + (cone[0] - vStart); 1772 coneNew[1] = vStartNew + (cone[1] - vStart); 1773 coneNew[(r+1)%2] = newv; 1774 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1775 #if defined(PETSC_USE_DEBUG) 1776 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp, cStartNew, cEndNew); 1777 for (p = 0; p < 2; ++p) { 1778 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); 1779 } 1780 #endif 1781 } 1782 } 1783 /* Old vertices have identical supports */ 1784 for (v = vStart; v < vEnd; ++v) { 1785 const PetscInt newp = vStartNew + (v - vStart); 1786 const PetscInt *support, *cone; 1787 PetscInt size, s; 1788 1789 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1790 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1791 for (s = 0; s < size; ++s) { 1792 PetscInt r = 0; 1793 1794 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1795 if (cone[1] == v) r = 1; 1796 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1797 } 1798 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1799 #if defined(PETSC_USE_DEBUG) 1800 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1801 for (p = 0; p < size; ++p) { 1802 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); 1803 } 1804 #endif 1805 } 1806 /* Cell vertices have support of 2 cells */ 1807 for (c = cStart; c < cEnd; ++c) { 1808 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1809 1810 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1811 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1812 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1813 #if defined(PETSC_USE_DEBUG) 1814 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1815 for (p = 0; p < 2; ++p) { 1816 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); 1817 } 1818 #endif 1819 } 1820 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1821 break; 1822 case REFINER_SIMPLEX_2D: 1823 /* 1824 2 1825 |\ 1826 | \ 1827 | \ 1828 | \ 1829 | C \ 1830 | \ 1831 | \ 1832 2---1---1 1833 |\ D / \ 1834 | 2 0 \ 1835 |A \ / B \ 1836 0---0-------1 1837 */ 1838 /* All cells have 3 faces */ 1839 for (c = cStart; c < cEnd; ++c) { 1840 const PetscInt newp = cStartNew + (c - cStart)*4; 1841 const PetscInt *cone, *ornt; 1842 PetscInt coneNew[3], orntNew[3]; 1843 1844 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1845 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1846 /* A triangle */ 1847 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1848 orntNew[0] = ornt[0]; 1849 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1850 orntNew[1] = -2; 1851 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1852 orntNew[2] = ornt[2]; 1853 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1854 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1855 #if defined(PETSC_USE_DEBUG) 1856 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); 1857 for (p = 0; p < 3; ++p) { 1858 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); 1859 } 1860 #endif 1861 /* B triangle */ 1862 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1863 orntNew[0] = ornt[0]; 1864 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1865 orntNew[1] = ornt[1]; 1866 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1867 orntNew[2] = -2; 1868 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1869 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1870 #if defined(PETSC_USE_DEBUG) 1871 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); 1872 for (p = 0; p < 3; ++p) { 1873 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); 1874 } 1875 #endif 1876 /* C triangle */ 1877 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1878 orntNew[0] = -2; 1879 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1880 orntNew[1] = ornt[1]; 1881 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1882 orntNew[2] = ornt[2]; 1883 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1884 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1885 #if defined(PETSC_USE_DEBUG) 1886 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); 1887 for (p = 0; p < 3; ++p) { 1888 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); 1889 } 1890 #endif 1891 /* D triangle */ 1892 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1893 orntNew[0] = 0; 1894 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1895 orntNew[1] = 0; 1896 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1897 orntNew[2] = 0; 1898 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1899 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1900 #if defined(PETSC_USE_DEBUG) 1901 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); 1902 for (p = 0; p < 3; ++p) { 1903 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); 1904 } 1905 #endif 1906 } 1907 /* Split faces have 2 vertices and the same cells as the parent */ 1908 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1909 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1910 for (f = fStart; f < fEnd; ++f) { 1911 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1912 1913 for (r = 0; r < 2; ++r) { 1914 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1915 const PetscInt *cone, *ornt, *support; 1916 PetscInt coneNew[2], coneSize, c, supportSize, s; 1917 1918 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1919 coneNew[0] = vStartNew + (cone[0] - vStart); 1920 coneNew[1] = vStartNew + (cone[1] - vStart); 1921 coneNew[(r+1)%2] = newv; 1922 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1923 #if defined(PETSC_USE_DEBUG) 1924 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1925 for (p = 0; p < 2; ++p) { 1926 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); 1927 } 1928 #endif 1929 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1930 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1931 for (s = 0; s < supportSize; ++s) { 1932 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1933 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1934 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1935 for (c = 0; c < coneSize; ++c) { 1936 if (cone[c] == f) break; 1937 } 1938 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1939 } 1940 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1941 #if defined(PETSC_USE_DEBUG) 1942 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1943 for (p = 0; p < supportSize; ++p) { 1944 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); 1945 } 1946 #endif 1947 } 1948 } 1949 /* Interior faces have 2 vertices and 2 cells */ 1950 for (c = cStart; c < cEnd; ++c) { 1951 const PetscInt *cone; 1952 1953 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1954 for (r = 0; r < 3; ++r) { 1955 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1956 PetscInt coneNew[2]; 1957 PetscInt supportNew[2]; 1958 1959 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1960 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1961 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1962 #if defined(PETSC_USE_DEBUG) 1963 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1964 for (p = 0; p < 2; ++p) { 1965 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); 1966 } 1967 #endif 1968 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1969 supportNew[1] = (c - cStart)*4 + 3; 1970 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1971 #if defined(PETSC_USE_DEBUG) 1972 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1973 for (p = 0; p < 2; ++p) { 1974 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); 1975 } 1976 #endif 1977 } 1978 } 1979 /* Old vertices have identical supports */ 1980 for (v = vStart; v < vEnd; ++v) { 1981 const PetscInt newp = vStartNew + (v - vStart); 1982 const PetscInt *support, *cone; 1983 PetscInt size, s; 1984 1985 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1986 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1987 for (s = 0; s < size; ++s) { 1988 PetscInt r = 0; 1989 1990 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1991 if (cone[1] == v) r = 1; 1992 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1993 } 1994 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1995 #if defined(PETSC_USE_DEBUG) 1996 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1997 for (p = 0; p < size; ++p) { 1998 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); 1999 } 2000 #endif 2001 } 2002 /* Face vertices have 2 + cells*2 supports */ 2003 for (f = fStart; f < fEnd; ++f) { 2004 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2005 const PetscInt *cone, *support; 2006 PetscInt size, s; 2007 2008 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2009 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2010 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2011 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2012 for (s = 0; s < size; ++s) { 2013 PetscInt r = 0; 2014 2015 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2016 if (cone[1] == f) r = 1; 2017 else if (cone[2] == f) r = 2; 2018 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 2019 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2020 } 2021 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2022 #if defined(PETSC_USE_DEBUG) 2023 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2024 for (p = 0; p < 2+size*2; ++p) { 2025 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); 2026 } 2027 #endif 2028 } 2029 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2030 break; 2031 case REFINER_SIMPLEX_TO_HEX_2D: 2032 /* 2033 2 2034 |\ 2035 | \ 2036 | \ 2037 | \ 2038 | C \ 2039 | \ 2040 2 1 2041 |\ / \ 2042 | 2 1 \ 2043 | \/ \ 2044 | | \ 2045 |A | B \ 2046 | 0 \ 2047 | | \ 2048 0---0----------1 2049 */ 2050 /* All cells have 4 faces */ 2051 for (c = cStart; c < cEnd; ++c) { 2052 const PetscInt newp = cStartNew + (c - cStart)*3; 2053 const PetscInt *cone, *ornt; 2054 PetscInt coneNew[4], orntNew[4]; 2055 2056 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2057 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2058 /* A quad */ 2059 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2060 orntNew[0] = ornt[0]; 2061 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2062 orntNew[1] = 0; 2063 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2064 orntNew[2] = -2; 2065 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2066 orntNew[3] = ornt[2]; 2067 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2068 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2069 #if defined(PETSC_USE_DEBUG) 2070 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); 2071 for (p = 0; p < 4; ++p) { 2072 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); 2073 } 2074 #endif 2075 /* B quad */ 2076 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2077 orntNew[0] = ornt[0]; 2078 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2079 orntNew[1] = ornt[1]; 2080 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2081 orntNew[2] = 0; 2082 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2083 orntNew[3] = -2; 2084 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2085 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2086 #if defined(PETSC_USE_DEBUG) 2087 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); 2088 for (p = 0; p < 4; ++p) { 2089 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); 2090 } 2091 #endif 2092 /* C quad */ 2093 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2094 orntNew[0] = ornt[1]; 2095 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2096 orntNew[1] = ornt[2]; 2097 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2098 orntNew[2] = 0; 2099 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2100 orntNew[3] = -2; 2101 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2102 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2103 #if defined(PETSC_USE_DEBUG) 2104 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); 2105 for (p = 0; p < 4; ++p) { 2106 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); 2107 } 2108 #endif 2109 } 2110 /* Split faces have 2 vertices and the same cells as the parent */ 2111 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2112 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2113 for (f = fStart; f < fEnd; ++f) { 2114 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2115 2116 for (r = 0; r < 2; ++r) { 2117 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2118 const PetscInt *cone, *ornt, *support; 2119 PetscInt coneNew[2], coneSize, c, supportSize, s; 2120 2121 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2122 coneNew[0] = vStartNew + (cone[0] - vStart); 2123 coneNew[1] = vStartNew + (cone[1] - vStart); 2124 coneNew[(r+1)%2] = newv; 2125 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2126 #if defined(PETSC_USE_DEBUG) 2127 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2128 for (p = 0; p < 2; ++p) { 2129 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); 2130 } 2131 #endif 2132 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2133 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2134 for (s = 0; s < supportSize; ++s) { 2135 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2136 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2137 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2138 for (c = 0; c < coneSize; ++c) { 2139 if (cone[c] == f) break; 2140 } 2141 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2142 } 2143 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2144 #if defined(PETSC_USE_DEBUG) 2145 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2146 for (p = 0; p < supportSize; ++p) { 2147 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); 2148 } 2149 #endif 2150 } 2151 } 2152 /* Interior faces have 2 vertices and 2 cells */ 2153 for (c = cStart; c < cEnd; ++c) { 2154 const PetscInt *cone; 2155 2156 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2157 for (r = 0; r < 3; ++r) { 2158 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2159 PetscInt coneNew[2]; 2160 PetscInt supportNew[2]; 2161 2162 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2163 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2164 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2165 #if defined(PETSC_USE_DEBUG) 2166 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2167 for (p = 0; p < 2; ++p) { 2168 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); 2169 } 2170 #endif 2171 supportNew[0] = (c - cStart)*3 + r%3; 2172 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2173 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2174 #if defined(PETSC_USE_DEBUG) 2175 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2176 for (p = 0; p < 2; ++p) { 2177 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); 2178 } 2179 #endif 2180 } 2181 } 2182 /* Old vertices have identical supports */ 2183 for (v = vStart; v < vEnd; ++v) { 2184 const PetscInt newp = vStartNew + (v - vStart); 2185 const PetscInt *support, *cone; 2186 PetscInt size, s; 2187 2188 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2189 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2190 for (s = 0; s < size; ++s) { 2191 PetscInt r = 0; 2192 2193 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2194 if (cone[1] == v) r = 1; 2195 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2196 } 2197 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2198 #if defined(PETSC_USE_DEBUG) 2199 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2200 for (p = 0; p < size; ++p) { 2201 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); 2202 } 2203 #endif 2204 } 2205 /* Split-face vertices have cells + 2 supports */ 2206 for (f = fStart; f < fEnd; ++f) { 2207 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2208 const PetscInt *cone, *support; 2209 PetscInt size, s; 2210 2211 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2212 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2213 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2214 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2215 for (s = 0; s < size; ++s) { 2216 PetscInt r = 0; 2217 2218 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2219 if (cone[1] == f) r = 1; 2220 else if (cone[2] == f) r = 2; 2221 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2222 } 2223 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2224 #if defined(PETSC_USE_DEBUG) 2225 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2226 for (p = 0; p < 2+size; ++p) { 2227 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); 2228 } 2229 #endif 2230 } 2231 /* Interior vertices have 3 supports */ 2232 for (c = cStart; c < cEnd; ++c) { 2233 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2234 2235 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2236 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2237 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2238 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2239 } 2240 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2241 break; 2242 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 2243 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2244 cMax = PetscMin(cEnd, cMax); 2245 for (c = cStart; c < cMax; ++c) { 2246 const PetscInt newp = cStartNew + (c - cStart)*3; 2247 const PetscInt *cone, *ornt; 2248 PetscInt coneNew[4], orntNew[4]; 2249 2250 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2251 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2252 /* A quad */ 2253 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2254 orntNew[0] = ornt[0]; 2255 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2256 orntNew[1] = 0; 2257 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2258 orntNew[2] = -2; 2259 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2260 orntNew[3] = ornt[2]; 2261 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2262 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2263 #if defined(PETSC_USE_DEBUG) 2264 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); 2265 for (p = 0; p < 4; ++p) { 2266 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); 2267 } 2268 #endif 2269 /* B quad */ 2270 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2271 orntNew[0] = ornt[0]; 2272 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2273 orntNew[1] = ornt[1]; 2274 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2275 orntNew[2] = 0; 2276 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2277 orntNew[3] = -2; 2278 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2279 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2280 #if defined(PETSC_USE_DEBUG) 2281 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); 2282 for (p = 0; p < 4; ++p) { 2283 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); 2284 } 2285 #endif 2286 /* C quad */ 2287 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2288 orntNew[0] = ornt[1]; 2289 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2290 orntNew[1] = ornt[2]; 2291 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2292 orntNew[2] = 0; 2293 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2294 orntNew[3] = -2; 2295 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2296 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2297 #if defined(PETSC_USE_DEBUG) 2298 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); 2299 for (p = 0; p < 4; ++p) { 2300 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); 2301 } 2302 #endif 2303 } 2304 /* 2305 2---------1---------3 2306 | | | 2307 | D 1 C | 2308 | | | 2309 2----2----0----3----3 2310 | | | 2311 | A 0 B | 2312 | | | 2313 0---------0---------1 2314 */ 2315 /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */ 2316 for (c = cMax; c < cEnd; ++c) { 2317 const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4; 2318 const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4; 2319 const PetscInt *cone, *ornt; 2320 PetscInt coneNew[4], orntNew[4]; 2321 2322 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2323 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2324 /* A quad */ 2325 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2326 orntNew[0] = ornt[0]; 2327 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2328 orntNew[1] = 0; 2329 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2330 orntNew[2] = -2; 2331 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2332 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2333 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2334 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2335 #if defined(PETSC_USE_DEBUG) 2336 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); 2337 for (p = 0; p < 4; ++p) { 2338 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); 2339 } 2340 #endif 2341 /* B quad */ 2342 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2343 orntNew[0] = ornt[0]; 2344 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2345 orntNew[1] = ornt[3]; 2346 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2347 orntNew[2] = 0; 2348 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2349 orntNew[3] = -2; 2350 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2351 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2352 #if defined(PETSC_USE_DEBUG) 2353 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); 2354 for (p = 0; p < 4; ++p) { 2355 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); 2356 } 2357 #endif 2358 /* C quad */ 2359 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2360 orntNew[0] = -2; 2361 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2362 orntNew[1] = ornt[3]; 2363 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2364 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2365 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2366 orntNew[3] = 0; 2367 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2368 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2369 #if defined(PETSC_USE_DEBUG) 2370 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); 2371 for (p = 0; p < 4; ++p) { 2372 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); 2373 } 2374 #endif 2375 /* D quad */ 2376 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2377 orntNew[0] = 0; 2378 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2379 orntNew[1] = -2; 2380 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2381 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2382 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2383 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2384 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2385 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2386 #if defined(PETSC_USE_DEBUG) 2387 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); 2388 for (p = 0; p < 4; ++p) { 2389 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); 2390 } 2391 #endif 2392 } 2393 /* Split faces have 2 vertices and the same cells as the parent */ 2394 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2395 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2396 for (f = fStart; f < fEnd; ++f) { 2397 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2398 2399 for (r = 0; r < 2; ++r) { 2400 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2401 const PetscInt *cone, *ornt, *support; 2402 PetscInt coneNew[2], coneSize, c, supportSize, s; 2403 2404 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2405 coneNew[0] = vStartNew + (cone[0] - vStart); 2406 coneNew[1] = vStartNew + (cone[1] - vStart); 2407 coneNew[(r+1)%2] = newv; 2408 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2409 #if defined(PETSC_USE_DEBUG) 2410 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2411 for (p = 0; p < 2; ++p) { 2412 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); 2413 } 2414 #endif 2415 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2416 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2417 for (s = 0; s < supportSize; ++s) { 2418 const PetscInt p2q[4][2] = { {0, 1}, 2419 {3, 2}, 2420 {0, 3}, 2421 {1, 2} }; 2422 2423 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2424 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2425 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2426 for (c = 0; c < coneSize; ++c) { 2427 if (cone[c] == f) break; 2428 } 2429 if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2430 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]); 2431 else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2432 } 2433 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2434 #if defined(PETSC_USE_DEBUG) 2435 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2436 for (p = 0; p < supportSize; ++p) { 2437 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); 2438 } 2439 #endif 2440 } 2441 } 2442 /* Interior faces have 2 vertices and 2 cells */ 2443 for (c = cStart; c < cMax; ++c) { 2444 const PetscInt *cone; 2445 2446 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2447 for (r = 0; r < 3; ++r) { 2448 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2449 PetscInt coneNew[2]; 2450 PetscInt supportNew[2]; 2451 2452 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2453 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2454 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2455 #if defined(PETSC_USE_DEBUG) 2456 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2457 for (p = 0; p < 2; ++p) { 2458 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); 2459 } 2460 #endif 2461 supportNew[0] = (c - cStart)*3 + r%3; 2462 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2463 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2464 #if defined(PETSC_USE_DEBUG) 2465 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2466 for (p = 0; p < 2; ++p) { 2467 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); 2468 } 2469 #endif 2470 } 2471 } 2472 /* Hybrid interior faces have 2 vertices and 2 cells */ 2473 for (c = cMax; c < cEnd; ++c) { 2474 const PetscInt *cone; 2475 PetscInt coneNew[2], supportNew[2]; 2476 2477 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2478 for (r = 0; r < 4; ++r) { 2479 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 2480 2481 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2482 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax); 2483 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2484 #if defined(PETSC_USE_DEBUG) 2485 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2486 for (p = 0; p < 2; ++p) { 2487 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); 2488 } 2489 #endif 2490 if (r==0) { 2491 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2492 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2493 } else if (r==1) { 2494 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2495 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2496 } else if (r==2) { 2497 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2498 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2499 } else { 2500 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2501 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2502 } 2503 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2504 #if defined(PETSC_USE_DEBUG) 2505 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2506 for (p = 0; p < 2; ++p) { 2507 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); 2508 } 2509 #endif 2510 } 2511 } 2512 /* Old vertices have identical supports */ 2513 for (v = vStart; v < vEnd; ++v) { 2514 const PetscInt newp = vStartNew + (v - vStart); 2515 const PetscInt *support, *cone; 2516 PetscInt size, s; 2517 2518 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2519 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2520 for (s = 0; s < size; ++s) { 2521 PetscInt r = 0; 2522 2523 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2524 if (cone[1] == v) r = 1; 2525 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2526 } 2527 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2528 #if defined(PETSC_USE_DEBUG) 2529 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2530 for (p = 0; p < size; ++p) { 2531 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); 2532 } 2533 #endif 2534 } 2535 /* Split-face vertices have cells + 2 supports */ 2536 for (f = fStart; f < fEnd; ++f) { 2537 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2538 const PetscInt *cone, *support; 2539 PetscInt size, s; 2540 2541 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2542 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2543 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2544 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2545 for (s = 0; s < size; ++s) { 2546 PetscInt r = 0, coneSize; 2547 2548 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2549 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2550 if (coneSize == 3) { 2551 if (cone[1] == f) r = 1; 2552 else if (cone[2] == f) r = 2; 2553 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2554 } else if (coneSize == 4) { 2555 if (cone[1] == f) r = 1; 2556 else if (cone[2] == f) r = 2; 2557 else if (cone[3] == f) r = 3; 2558 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r; 2559 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2560 } 2561 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2562 #if defined(PETSC_USE_DEBUG) 2563 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2564 for (p = 0; p < 2+size; ++p) { 2565 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); 2566 } 2567 #endif 2568 } 2569 /* Interior vertices have 3 supports */ 2570 for (c = cStart; c < cMax; ++c) { 2571 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2572 2573 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2574 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2575 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2576 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2577 } 2578 /* Hybrid interior vertices have 4 supports */ 2579 for (c = cMax; c < cEnd; ++c) { 2580 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2581 2582 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0; 2583 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1; 2584 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2; 2585 supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3; 2586 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2587 } 2588 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2589 break; 2590 case REFINER_HEX_2D: 2591 /* 2592 3---------2---------2 2593 | | | 2594 | D 2 C | 2595 | | | 2596 3----3----0----1----1 2597 | | | 2598 | A 0 B | 2599 | | | 2600 0---------0---------1 2601 */ 2602 /* All cells have 4 faces */ 2603 for (c = cStart; c < cEnd; ++c) { 2604 const PetscInt newp = (c - cStart)*4; 2605 const PetscInt *cone, *ornt; 2606 PetscInt coneNew[4], orntNew[4]; 2607 2608 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2609 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2610 /* A quad */ 2611 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2612 orntNew[0] = ornt[0]; 2613 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2614 orntNew[1] = 0; 2615 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2616 orntNew[2] = -2; 2617 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2618 orntNew[3] = ornt[3]; 2619 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2620 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2621 #if defined(PETSC_USE_DEBUG) 2622 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); 2623 for (p = 0; p < 4; ++p) { 2624 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); 2625 } 2626 #endif 2627 /* B quad */ 2628 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2629 orntNew[0] = ornt[0]; 2630 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2631 orntNew[1] = ornt[1]; 2632 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2633 orntNew[2] = -2; 2634 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2635 orntNew[3] = -2; 2636 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2637 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2638 #if defined(PETSC_USE_DEBUG) 2639 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); 2640 for (p = 0; p < 4; ++p) { 2641 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); 2642 } 2643 #endif 2644 /* C quad */ 2645 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2646 orntNew[0] = 0; 2647 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2648 orntNew[1] = ornt[1]; 2649 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2650 orntNew[2] = ornt[2]; 2651 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2652 orntNew[3] = -2; 2653 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2654 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2655 #if defined(PETSC_USE_DEBUG) 2656 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); 2657 for (p = 0; p < 4; ++p) { 2658 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); 2659 } 2660 #endif 2661 /* D quad */ 2662 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2663 orntNew[0] = 0; 2664 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2665 orntNew[1] = 0; 2666 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2667 orntNew[2] = ornt[2]; 2668 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2669 orntNew[3] = ornt[3]; 2670 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2671 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2672 #if defined(PETSC_USE_DEBUG) 2673 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); 2674 for (p = 0; p < 4; ++p) { 2675 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); 2676 } 2677 #endif 2678 } 2679 /* Split faces have 2 vertices and the same cells as the parent */ 2680 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2681 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2682 for (f = fStart; f < fEnd; ++f) { 2683 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2684 2685 for (r = 0; r < 2; ++r) { 2686 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2687 const PetscInt *cone, *ornt, *support; 2688 PetscInt coneNew[2], coneSize, c, supportSize, s; 2689 2690 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2691 coneNew[0] = vStartNew + (cone[0] - vStart); 2692 coneNew[1] = vStartNew + (cone[1] - vStart); 2693 coneNew[(r+1)%2] = newv; 2694 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2695 #if defined(PETSC_USE_DEBUG) 2696 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2697 for (p = 0; p < 2; ++p) { 2698 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); 2699 } 2700 #endif 2701 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2702 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2703 for (s = 0; s < supportSize; ++s) { 2704 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2705 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2706 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2707 for (c = 0; c < coneSize; ++c) { 2708 if (cone[c] == f) break; 2709 } 2710 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2711 } 2712 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2713 #if defined(PETSC_USE_DEBUG) 2714 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2715 for (p = 0; p < supportSize; ++p) { 2716 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); 2717 } 2718 #endif 2719 } 2720 } 2721 /* Interior faces have 2 vertices and 2 cells */ 2722 for (c = cStart; c < cEnd; ++c) { 2723 const PetscInt *cone; 2724 PetscInt coneNew[2], supportNew[2]; 2725 2726 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2727 for (r = 0; r < 4; ++r) { 2728 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2729 2730 if (r==1 || r==2) { 2731 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2732 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2733 } else { 2734 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2735 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2736 } 2737 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2738 #if defined(PETSC_USE_DEBUG) 2739 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2740 for (p = 0; p < 2; ++p) { 2741 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); 2742 } 2743 #endif 2744 supportNew[0] = (c - cStart)*4 + r; 2745 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2746 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2747 #if defined(PETSC_USE_DEBUG) 2748 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2749 for (p = 0; p < 2; ++p) { 2750 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); 2751 } 2752 #endif 2753 } 2754 } 2755 /* Old vertices have identical supports */ 2756 for (v = vStart; v < vEnd; ++v) { 2757 const PetscInt newp = vStartNew + (v - vStart); 2758 const PetscInt *support, *cone; 2759 PetscInt size, s; 2760 2761 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2762 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2763 for (s = 0; s < size; ++s) { 2764 PetscInt r = 0; 2765 2766 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2767 if (cone[1] == v) r = 1; 2768 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2769 } 2770 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2771 #if defined(PETSC_USE_DEBUG) 2772 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2773 for (p = 0; p < size; ++p) { 2774 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); 2775 } 2776 #endif 2777 } 2778 /* Face vertices have 2 + cells supports */ 2779 for (f = fStart; f < fEnd; ++f) { 2780 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2781 const PetscInt *cone, *support; 2782 PetscInt size, s; 2783 2784 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2785 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2786 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2787 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2788 for (s = 0; s < size; ++s) { 2789 PetscInt r = 0; 2790 2791 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2792 if (cone[1] == f) r = 1; 2793 else if (cone[2] == f) r = 2; 2794 else if (cone[3] == f) r = 3; 2795 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 2796 } 2797 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2798 #if defined(PETSC_USE_DEBUG) 2799 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2800 for (p = 0; p < 2+size; ++p) { 2801 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); 2802 } 2803 #endif 2804 } 2805 /* Cell vertices have 4 supports */ 2806 for (c = cStart; c < cEnd; ++c) { 2807 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2808 PetscInt supportNew[4]; 2809 2810 for (r = 0; r < 4; ++r) { 2811 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2812 } 2813 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2814 } 2815 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2816 break; 2817 case REFINER_HYBRID_SIMPLEX_2D: 2818 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2819 cMax = PetscMin(cEnd, cMax); 2820 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2821 fMax = PetscMin(fEnd, fMax); 2822 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2823 /* Interior cells have 3 faces */ 2824 for (c = cStart; c < cMax; ++c) { 2825 const PetscInt newp = cStartNew + (c - cStart)*4; 2826 const PetscInt *cone, *ornt; 2827 PetscInt coneNew[3], orntNew[3]; 2828 2829 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2830 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2831 /* A triangle */ 2832 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2833 orntNew[0] = ornt[0]; 2834 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2835 orntNew[1] = -2; 2836 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2837 orntNew[2] = ornt[2]; 2838 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2839 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2840 #if defined(PETSC_USE_DEBUG) 2841 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); 2842 for (p = 0; p < 3; ++p) { 2843 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); 2844 } 2845 #endif 2846 /* B triangle */ 2847 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2848 orntNew[0] = ornt[0]; 2849 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2850 orntNew[1] = ornt[1]; 2851 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2852 orntNew[2] = -2; 2853 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2854 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2855 #if defined(PETSC_USE_DEBUG) 2856 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); 2857 for (p = 0; p < 3; ++p) { 2858 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); 2859 } 2860 #endif 2861 /* C triangle */ 2862 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2863 orntNew[0] = -2; 2864 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2865 orntNew[1] = ornt[1]; 2866 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2867 orntNew[2] = ornt[2]; 2868 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2869 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2870 #if defined(PETSC_USE_DEBUG) 2871 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); 2872 for (p = 0; p < 3; ++p) { 2873 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); 2874 } 2875 #endif 2876 /* D triangle */ 2877 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2878 orntNew[0] = 0; 2879 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2880 orntNew[1] = 0; 2881 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2882 orntNew[2] = 0; 2883 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2884 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2885 #if defined(PETSC_USE_DEBUG) 2886 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); 2887 for (p = 0; p < 3; ++p) { 2888 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); 2889 } 2890 #endif 2891 } 2892 /* 2893 2----3----3 2894 | | 2895 | B | 2896 | | 2897 0----4--- 1 2898 | | 2899 | A | 2900 | | 2901 0----2----1 2902 */ 2903 /* Hybrid cells have 4 faces */ 2904 for (c = cMax; c < cEnd; ++c) { 2905 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2906 const PetscInt *cone, *ornt; 2907 PetscInt coneNew[4], orntNew[4], r; 2908 2909 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2910 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2911 r = (ornt[0] < 0 ? 1 : 0); 2912 /* A quad */ 2913 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2914 orntNew[0] = ornt[0]; 2915 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2916 orntNew[1] = ornt[1]; 2917 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2918 orntNew[2+r] = 0; 2919 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2920 orntNew[3-r] = 0; 2921 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2922 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2923 #if defined(PETSC_USE_DEBUG) 2924 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); 2925 for (p = 0; p < 4; ++p) { 2926 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); 2927 } 2928 #endif 2929 /* B quad */ 2930 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2931 orntNew[0] = ornt[0]; 2932 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2933 orntNew[1] = ornt[1]; 2934 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2935 orntNew[2+r] = 0; 2936 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2937 orntNew[3-r] = 0; 2938 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2939 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2940 #if defined(PETSC_USE_DEBUG) 2941 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); 2942 for (p = 0; p < 4; ++p) { 2943 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); 2944 } 2945 #endif 2946 } 2947 /* Interior split faces have 2 vertices and the same cells as the parent */ 2948 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2949 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2950 for (f = fStart; f < fMax; ++f) { 2951 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2952 2953 for (r = 0; r < 2; ++r) { 2954 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2955 const PetscInt *cone, *ornt, *support; 2956 PetscInt coneNew[2], coneSize, c, supportSize, s; 2957 2958 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2959 coneNew[0] = vStartNew + (cone[0] - vStart); 2960 coneNew[1] = vStartNew + (cone[1] - vStart); 2961 coneNew[(r+1)%2] = newv; 2962 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2963 #if defined(PETSC_USE_DEBUG) 2964 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2965 for (p = 0; p < 2; ++p) { 2966 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); 2967 } 2968 #endif 2969 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2970 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2971 for (s = 0; s < supportSize; ++s) { 2972 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2973 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2974 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2975 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2976 if (support[s] >= cMax) { 2977 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2978 } else { 2979 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2980 } 2981 } 2982 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2983 #if defined(PETSC_USE_DEBUG) 2984 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2985 for (p = 0; p < supportSize; ++p) { 2986 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); 2987 } 2988 #endif 2989 } 2990 } 2991 /* Interior cell faces have 2 vertices and 2 cells */ 2992 for (c = cStart; c < cMax; ++c) { 2993 const PetscInt *cone; 2994 2995 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2996 for (r = 0; r < 3; ++r) { 2997 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 2998 PetscInt coneNew[2]; 2999 PetscInt supportNew[2]; 3000 3001 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3002 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 3003 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3004 #if defined(PETSC_USE_DEBUG) 3005 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3006 for (p = 0; p < 2; ++p) { 3007 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); 3008 } 3009 #endif 3010 supportNew[0] = (c - cStart)*4 + (r+1)%3; 3011 supportNew[1] = (c - cStart)*4 + 3; 3012 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3013 #if defined(PETSC_USE_DEBUG) 3014 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3015 for (p = 0; p < 2; ++p) { 3016 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); 3017 } 3018 #endif 3019 } 3020 } 3021 /* Interior hybrid faces have 2 vertices and the same cells */ 3022 for (f = fMax; f < fEnd; ++f) { 3023 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 3024 const PetscInt *cone, *ornt; 3025 const PetscInt *support; 3026 PetscInt coneNew[2]; 3027 PetscInt supportNew[2]; 3028 PetscInt size, s, r; 3029 3030 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3031 coneNew[0] = vStartNew + (cone[0] - vStart); 3032 coneNew[1] = vStartNew + (cone[1] - vStart); 3033 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3034 #if defined(PETSC_USE_DEBUG) 3035 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3036 for (p = 0; p < 2; ++p) { 3037 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); 3038 } 3039 #endif 3040 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3041 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3042 for (s = 0; s < size; ++s) { 3043 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3044 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3045 for (r = 0; r < 2; ++r) { 3046 if (cone[r+2] == f) break; 3047 } 3048 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 3049 } 3050 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3051 #if defined(PETSC_USE_DEBUG) 3052 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3053 for (p = 0; p < size; ++p) { 3054 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); 3055 } 3056 #endif 3057 } 3058 /* Cell hybrid faces have 2 vertices and 2 cells */ 3059 for (c = cMax; c < cEnd; ++c) { 3060 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 3061 const PetscInt *cone; 3062 PetscInt coneNew[2]; 3063 PetscInt supportNew[2]; 3064 3065 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3066 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3067 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3068 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3069 #if defined(PETSC_USE_DEBUG) 3070 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3071 for (p = 0; p < 2; ++p) { 3072 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); 3073 } 3074 #endif 3075 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3076 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3077 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3078 #if defined(PETSC_USE_DEBUG) 3079 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3080 for (p = 0; p < 2; ++p) { 3081 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); 3082 } 3083 #endif 3084 } 3085 /* Old vertices have identical supports */ 3086 for (v = vStart; v < vEnd; ++v) { 3087 const PetscInt newp = vStartNew + (v - vStart); 3088 const PetscInt *support, *cone; 3089 PetscInt size, s; 3090 3091 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3092 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3093 for (s = 0; s < size; ++s) { 3094 if (support[s] >= fMax) { 3095 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 3096 } else { 3097 PetscInt r = 0; 3098 3099 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3100 if (cone[1] == v) r = 1; 3101 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3102 } 3103 } 3104 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3105 #if defined(PETSC_USE_DEBUG) 3106 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3107 for (p = 0; p < size; ++p) { 3108 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); 3109 } 3110 #endif 3111 } 3112 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 3113 for (f = fStart; f < fMax; ++f) { 3114 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3115 const PetscInt *cone, *support; 3116 PetscInt size, newSize = 2, s; 3117 3118 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3119 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3120 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3121 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3122 for (s = 0; s < size; ++s) { 3123 PetscInt r = 0; 3124 3125 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3126 if (support[s] >= cMax) { 3127 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 3128 3129 newSize += 1; 3130 } else { 3131 if (cone[1] == f) r = 1; 3132 else if (cone[2] == f) r = 2; 3133 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 3134 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 3135 3136 newSize += 2; 3137 } 3138 } 3139 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3140 #if defined(PETSC_USE_DEBUG) 3141 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3142 for (p = 0; p < newSize; ++p) { 3143 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); 3144 } 3145 #endif 3146 } 3147 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3148 break; 3149 case REFINER_HYBRID_HEX_2D: 3150 /* Hybrid Hex 2D */ 3151 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 3152 cMax = PetscMin(cEnd, cMax); 3153 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 3154 fMax = PetscMin(fEnd, fMax); 3155 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 3156 /* Interior cells have 4 faces */ 3157 for (c = cStart; c < cMax; ++c) { 3158 const PetscInt newp = cStartNew + (c - cStart)*4; 3159 const PetscInt *cone, *ornt; 3160 PetscInt coneNew[4], orntNew[4]; 3161 3162 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3163 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3164 /* A quad */ 3165 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3166 orntNew[0] = ornt[0]; 3167 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3168 orntNew[1] = 0; 3169 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3170 orntNew[2] = -2; 3171 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 3172 orntNew[3] = ornt[3]; 3173 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3174 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3175 #if defined(PETSC_USE_DEBUG) 3176 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); 3177 for (p = 0; p < 4; ++p) { 3178 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); 3179 } 3180 #endif 3181 /* B quad */ 3182 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3183 orntNew[0] = ornt[0]; 3184 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3185 orntNew[1] = ornt[1]; 3186 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3187 orntNew[2] = 0; 3188 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3189 orntNew[3] = -2; 3190 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3191 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3192 #if defined(PETSC_USE_DEBUG) 3193 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); 3194 for (p = 0; p < 4; ++p) { 3195 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); 3196 } 3197 #endif 3198 /* C quad */ 3199 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3200 orntNew[0] = -2; 3201 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3202 orntNew[1] = ornt[1]; 3203 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 3204 orntNew[2] = ornt[2]; 3205 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3206 orntNew[3] = 0; 3207 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3208 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3209 #if defined(PETSC_USE_DEBUG) 3210 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); 3211 for (p = 0; p < 4; ++p) { 3212 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); 3213 } 3214 #endif 3215 /* D quad */ 3216 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3217 orntNew[0] = 0; 3218 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3219 orntNew[1] = -2; 3220 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 3221 orntNew[2] = ornt[2]; 3222 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 3223 orntNew[3] = ornt[3]; 3224 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3225 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3226 #if defined(PETSC_USE_DEBUG) 3227 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); 3228 for (p = 0; p < 4; ++p) { 3229 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); 3230 } 3231 #endif 3232 } 3233 /* 3234 2----3----3 3235 | | 3236 | B | 3237 | | 3238 0----4--- 1 3239 | | 3240 | A | 3241 | | 3242 0----2----1 3243 */ 3244 /* Hybrid cells have 4 faces */ 3245 for (c = cMax; c < cEnd; ++c) { 3246 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 3247 const PetscInt *cone, *ornt; 3248 PetscInt coneNew[4], orntNew[4]; 3249 3250 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3251 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3252 /* A quad */ 3253 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3254 orntNew[0] = ornt[0]; 3255 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3256 orntNew[1] = ornt[1]; 3257 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 3258 orntNew[2] = 0; 3259 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3260 orntNew[3] = 0; 3261 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3262 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3263 #if defined(PETSC_USE_DEBUG) 3264 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); 3265 for (p = 0; p < 4; ++p) { 3266 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); 3267 } 3268 #endif 3269 /* B quad */ 3270 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3271 orntNew[0] = ornt[0]; 3272 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3273 orntNew[1] = ornt[1]; 3274 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3275 orntNew[2] = 0; 3276 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 3277 orntNew[3] = 0; 3278 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3279 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3280 #if defined(PETSC_USE_DEBUG) 3281 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); 3282 for (p = 0; p < 4; ++p) { 3283 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); 3284 } 3285 #endif 3286 } 3287 /* Interior split faces have 2 vertices and the same cells as the parent */ 3288 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3289 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3290 for (f = fStart; f < fMax; ++f) { 3291 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 3292 3293 for (r = 0; r < 2; ++r) { 3294 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 3295 const PetscInt *cone, *ornt, *support; 3296 PetscInt coneNew[2], coneSize, c, supportSize, s; 3297 3298 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3299 coneNew[0] = vStartNew + (cone[0] - vStart); 3300 coneNew[1] = vStartNew + (cone[1] - vStart); 3301 coneNew[(r+1)%2] = newv; 3302 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3303 #if defined(PETSC_USE_DEBUG) 3304 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3305 for (p = 0; p < 2; ++p) { 3306 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); 3307 } 3308 #endif 3309 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3310 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3311 for (s = 0; s < supportSize; ++s) { 3312 if (support[s] >= cMax) { 3313 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3314 } else { 3315 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3316 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3317 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3318 for (c = 0; c < coneSize; ++c) { 3319 if (cone[c] == f) break; 3320 } 3321 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3322 } 3323 } 3324 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3325 #if defined(PETSC_USE_DEBUG) 3326 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3327 for (p = 0; p < supportSize; ++p) { 3328 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); 3329 } 3330 #endif 3331 } 3332 } 3333 /* Interior cell faces have 2 vertices and 2 cells */ 3334 for (c = cStart; c < cMax; ++c) { 3335 const PetscInt *cone; 3336 3337 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3338 for (r = 0; r < 4; ++r) { 3339 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3340 PetscInt coneNew[2], supportNew[2]; 3341 3342 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3343 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3344 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3345 #if defined(PETSC_USE_DEBUG) 3346 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3347 for (p = 0; p < 2; ++p) { 3348 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); 3349 } 3350 #endif 3351 supportNew[0] = (c - cStart)*4 + r; 3352 supportNew[1] = (c - cStart)*4 + (r+1)%4; 3353 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3354 #if defined(PETSC_USE_DEBUG) 3355 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3356 for (p = 0; p < 2; ++p) { 3357 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); 3358 } 3359 #endif 3360 } 3361 } 3362 /* Hybrid faces have 2 vertices and the same cells */ 3363 for (f = fMax; f < fEnd; ++f) { 3364 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 3365 const PetscInt *cone, *support; 3366 PetscInt coneNew[2], supportNew[2]; 3367 PetscInt size, s, r; 3368 3369 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3370 coneNew[0] = vStartNew + (cone[0] - vStart); 3371 coneNew[1] = vStartNew + (cone[1] - vStart); 3372 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3373 #if defined(PETSC_USE_DEBUG) 3374 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3375 for (p = 0; p < 2; ++p) { 3376 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); 3377 } 3378 #endif 3379 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3380 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3381 for (s = 0; s < size; ++s) { 3382 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3383 for (r = 0; r < 2; ++r) { 3384 if (cone[r+2] == f) break; 3385 } 3386 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3387 } 3388 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3389 #if defined(PETSC_USE_DEBUG) 3390 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3391 for (p = 0; p < size; ++p) { 3392 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); 3393 } 3394 #endif 3395 } 3396 /* Cell hybrid faces have 2 vertices and 2 cells */ 3397 for (c = cMax; c < cEnd; ++c) { 3398 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3399 const PetscInt *cone; 3400 PetscInt coneNew[2], supportNew[2]; 3401 3402 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3403 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3404 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3405 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3406 #if defined(PETSC_USE_DEBUG) 3407 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3408 for (p = 0; p < 2; ++p) { 3409 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); 3410 } 3411 #endif 3412 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3413 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3414 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3415 #if defined(PETSC_USE_DEBUG) 3416 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3417 for (p = 0; p < 2; ++p) { 3418 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); 3419 } 3420 #endif 3421 } 3422 /* Old vertices have identical supports */ 3423 for (v = vStart; v < vEnd; ++v) { 3424 const PetscInt newp = vStartNew + (v - vStart); 3425 const PetscInt *support, *cone; 3426 PetscInt size, s; 3427 3428 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3429 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3430 for (s = 0; s < size; ++s) { 3431 if (support[s] >= fMax) { 3432 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 3433 } else { 3434 PetscInt r = 0; 3435 3436 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3437 if (cone[1] == v) r = 1; 3438 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3439 } 3440 } 3441 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3442 #if defined(PETSC_USE_DEBUG) 3443 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3444 for (p = 0; p < size; ++p) { 3445 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); 3446 } 3447 #endif 3448 } 3449 /* Face vertices have 2 + cells supports */ 3450 for (f = fStart; f < fMax; ++f) { 3451 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3452 const PetscInt *cone, *support; 3453 PetscInt size, s; 3454 3455 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3456 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3457 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3458 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3459 for (s = 0; s < size; ++s) { 3460 PetscInt r = 0; 3461 3462 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3463 if (support[s] >= cMax) { 3464 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 3465 } else { 3466 if (cone[1] == f) r = 1; 3467 else if (cone[2] == f) r = 2; 3468 else if (cone[3] == f) r = 3; 3469 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 3470 } 3471 } 3472 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3473 #if defined(PETSC_USE_DEBUG) 3474 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3475 for (p = 0; p < 2+size; ++p) { 3476 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); 3477 } 3478 #endif 3479 } 3480 /* Cell vertices have 4 supports */ 3481 for (c = cStart; c < cMax; ++c) { 3482 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3483 PetscInt supportNew[4]; 3484 3485 for (r = 0; r < 4; ++r) { 3486 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3487 } 3488 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3489 } 3490 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3491 break; 3492 case REFINER_SIMPLEX_3D: 3493 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3494 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3495 for (c = cStart; c < cEnd; ++c) { 3496 const PetscInt newp = cStartNew + (c - cStart)*8; 3497 const PetscInt *cone, *ornt; 3498 PetscInt coneNew[4], orntNew[4]; 3499 3500 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3501 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3502 /* A tetrahedron: {0, a, c, d} */ 3503 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3504 orntNew[0] = ornt[0]; 3505 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3506 orntNew[1] = ornt[1]; 3507 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3508 orntNew[2] = ornt[2]; 3509 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3510 orntNew[3] = 0; 3511 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3512 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3513 #if defined(PETSC_USE_DEBUG) 3514 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); 3515 for (p = 0; p < 4; ++p) { 3516 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); 3517 } 3518 #endif 3519 /* B tetrahedron: {a, 1, b, e} */ 3520 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3521 orntNew[0] = ornt[0]; 3522 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3523 orntNew[1] = ornt[1]; 3524 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3525 orntNew[2] = 0; 3526 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3527 orntNew[3] = ornt[3]; 3528 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3529 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3530 #if defined(PETSC_USE_DEBUG) 3531 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); 3532 for (p = 0; p < 4; ++p) { 3533 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); 3534 } 3535 #endif 3536 /* C tetrahedron: {c, b, 2, f} */ 3537 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3538 orntNew[0] = ornt[0]; 3539 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3540 orntNew[1] = 0; 3541 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3542 orntNew[2] = ornt[2]; 3543 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3544 orntNew[3] = ornt[3]; 3545 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3546 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3547 #if defined(PETSC_USE_DEBUG) 3548 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); 3549 for (p = 0; p < 4; ++p) { 3550 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); 3551 } 3552 #endif 3553 /* D tetrahedron: {d, e, f, 3} */ 3554 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3555 orntNew[0] = 0; 3556 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3557 orntNew[1] = ornt[1]; 3558 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3559 orntNew[2] = ornt[2]; 3560 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3561 orntNew[3] = ornt[3]; 3562 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3563 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3564 #if defined(PETSC_USE_DEBUG) 3565 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); 3566 for (p = 0; p < 4; ++p) { 3567 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); 3568 } 3569 #endif 3570 /* A' tetrahedron: {c, d, a, f} */ 3571 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3572 orntNew[0] = -3; 3573 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3574 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3575 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3576 orntNew[2] = 0; 3577 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3578 orntNew[3] = 2; 3579 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3580 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3581 #if defined(PETSC_USE_DEBUG) 3582 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); 3583 for (p = 0; p < 4; ++p) { 3584 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); 3585 } 3586 #endif 3587 /* B' tetrahedron: {e, b, a, f} */ 3588 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3589 orntNew[0] = -2; 3590 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 3591 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 3592 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3593 orntNew[2] = 0; 3594 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3595 orntNew[3] = 0; 3596 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3597 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3598 #if defined(PETSC_USE_DEBUG) 3599 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); 3600 for (p = 0; p < 4; ++p) { 3601 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); 3602 } 3603 #endif 3604 /* C' tetrahedron: {f, a, c, b} */ 3605 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3606 orntNew[0] = -2; 3607 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3608 orntNew[1] = -2; 3609 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3610 orntNew[2] = -1; 3611 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 3612 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3613 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3614 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3615 #if defined(PETSC_USE_DEBUG) 3616 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); 3617 for (p = 0; p < 4; ++p) { 3618 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); 3619 } 3620 #endif 3621 /* D' tetrahedron: {f, a, e, d} */ 3622 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3623 orntNew[0] = -2; 3624 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3625 orntNew[1] = -1; 3626 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3627 orntNew[2] = -2; 3628 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 3629 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 3630 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3631 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3632 #if defined(PETSC_USE_DEBUG) 3633 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); 3634 for (p = 0; p < 4; ++p) { 3635 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); 3636 } 3637 #endif 3638 } 3639 /* Split faces have 3 edges and the same cells as the parent */ 3640 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3641 ierr = PetscMalloc1(2 + maxSupportSize*3, &supportRef);CHKERRQ(ierr); 3642 for (f = fStart; f < fEnd; ++f) { 3643 const PetscInt newp = fStartNew + (f - fStart)*4; 3644 const PetscInt *cone, *ornt, *support; 3645 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3646 3647 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3648 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3649 /* A triangle */ 3650 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3651 orntNew[0] = ornt[0]; 3652 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3653 orntNew[1] = -2; 3654 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3655 orntNew[2] = ornt[2]; 3656 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3657 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3658 #if defined(PETSC_USE_DEBUG) 3659 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); 3660 for (p = 0; p < 3; ++p) { 3661 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); 3662 } 3663 #endif 3664 /* B triangle */ 3665 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3666 orntNew[0] = ornt[0]; 3667 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3668 orntNew[1] = ornt[1]; 3669 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3670 orntNew[2] = -2; 3671 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3672 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3673 #if defined(PETSC_USE_DEBUG) 3674 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); 3675 for (p = 0; p < 3; ++p) { 3676 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); 3677 } 3678 #endif 3679 /* C triangle */ 3680 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3681 orntNew[0] = -2; 3682 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3683 orntNew[1] = ornt[1]; 3684 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3685 orntNew[2] = ornt[2]; 3686 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3687 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3688 #if defined(PETSC_USE_DEBUG) 3689 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); 3690 for (p = 0; p < 3; ++p) { 3691 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); 3692 } 3693 #endif 3694 /* D triangle */ 3695 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3696 orntNew[0] = 0; 3697 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3698 orntNew[1] = 0; 3699 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3700 orntNew[2] = 0; 3701 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3702 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3703 #if defined(PETSC_USE_DEBUG) 3704 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); 3705 for (p = 0; p < 3; ++p) { 3706 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); 3707 } 3708 #endif 3709 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3710 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3711 for (r = 0; r < 4; ++r) { 3712 for (s = 0; s < supportSize; ++s) { 3713 PetscInt subf; 3714 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3715 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3716 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3717 for (c = 0; c < coneSize; ++c) { 3718 if (cone[c] == f) break; 3719 } 3720 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3721 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3722 } 3723 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3724 #if defined(PETSC_USE_DEBUG) 3725 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); 3726 for (p = 0; p < supportSize; ++p) { 3727 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); 3728 } 3729 #endif 3730 } 3731 } 3732 /* Interior faces have 3 edges and 2 cells */ 3733 for (c = cStart; c < cEnd; ++c) { 3734 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 3735 const PetscInt *cone, *ornt; 3736 PetscInt coneNew[3], orntNew[3]; 3737 PetscInt supportNew[2]; 3738 3739 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3740 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3741 /* Face A: {c, a, d} */ 3742 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3743 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3744 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3745 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3746 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3747 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3748 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3749 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3750 #if defined(PETSC_USE_DEBUG) 3751 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3752 for (p = 0; p < 3; ++p) { 3753 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); 3754 } 3755 #endif 3756 supportNew[0] = (c - cStart)*8 + 0; 3757 supportNew[1] = (c - cStart)*8 + 0+4; 3758 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3759 #if defined(PETSC_USE_DEBUG) 3760 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3761 for (p = 0; p < 2; ++p) { 3762 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); 3763 } 3764 #endif 3765 ++newp; 3766 /* Face B: {a, b, e} */ 3767 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3768 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3769 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3770 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3771 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3772 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3773 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3774 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3775 #if defined(PETSC_USE_DEBUG) 3776 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3777 for (p = 0; p < 3; ++p) { 3778 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); 3779 } 3780 #endif 3781 supportNew[0] = (c - cStart)*8 + 1; 3782 supportNew[1] = (c - cStart)*8 + 1+4; 3783 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3784 #if defined(PETSC_USE_DEBUG) 3785 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3786 for (p = 0; p < 2; ++p) { 3787 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); 3788 } 3789 #endif 3790 ++newp; 3791 /* Face C: {c, f, b} */ 3792 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3793 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3794 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3795 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3796 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3797 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3798 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3799 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3800 #if defined(PETSC_USE_DEBUG) 3801 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3802 for (p = 0; p < 3; ++p) { 3803 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); 3804 } 3805 #endif 3806 supportNew[0] = (c - cStart)*8 + 2; 3807 supportNew[1] = (c - cStart)*8 + 2+4; 3808 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3809 #if defined(PETSC_USE_DEBUG) 3810 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3811 for (p = 0; p < 2; ++p) { 3812 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); 3813 } 3814 #endif 3815 ++newp; 3816 /* Face D: {d, e, f} */ 3817 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3818 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3819 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3820 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3821 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3822 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3823 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3824 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3825 #if defined(PETSC_USE_DEBUG) 3826 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3827 for (p = 0; p < 3; ++p) { 3828 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); 3829 } 3830 #endif 3831 supportNew[0] = (c - cStart)*8 + 3; 3832 supportNew[1] = (c - cStart)*8 + 3+4; 3833 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3834 #if defined(PETSC_USE_DEBUG) 3835 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3836 for (p = 0; p < 2; ++p) { 3837 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); 3838 } 3839 #endif 3840 ++newp; 3841 /* Face E: {d, f, a} */ 3842 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3843 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3844 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3845 orntNew[1] = -2; 3846 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3847 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3848 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3849 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3850 #if defined(PETSC_USE_DEBUG) 3851 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3852 for (p = 0; p < 3; ++p) { 3853 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); 3854 } 3855 #endif 3856 supportNew[0] = (c - cStart)*8 + 0+4; 3857 supportNew[1] = (c - cStart)*8 + 3+4; 3858 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3859 #if defined(PETSC_USE_DEBUG) 3860 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3861 for (p = 0; p < 2; ++p) { 3862 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); 3863 } 3864 #endif 3865 ++newp; 3866 /* Face F: {c, a, f} */ 3867 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3868 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3869 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3870 orntNew[1] = 0; 3871 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3872 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3873 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3874 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3875 #if defined(PETSC_USE_DEBUG) 3876 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3877 for (p = 0; p < 3; ++p) { 3878 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); 3879 } 3880 #endif 3881 supportNew[0] = (c - cStart)*8 + 0+4; 3882 supportNew[1] = (c - cStart)*8 + 2+4; 3883 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3884 #if defined(PETSC_USE_DEBUG) 3885 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3886 for (p = 0; p < 2; ++p) { 3887 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); 3888 } 3889 #endif 3890 ++newp; 3891 /* Face G: {e, a, f} */ 3892 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3893 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3894 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3895 orntNew[1] = 0; 3896 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3897 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3898 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3899 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3900 #if defined(PETSC_USE_DEBUG) 3901 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3902 for (p = 0; p < 3; ++p) { 3903 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); 3904 } 3905 #endif 3906 supportNew[0] = (c - cStart)*8 + 1+4; 3907 supportNew[1] = (c - cStart)*8 + 3+4; 3908 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3909 #if defined(PETSC_USE_DEBUG) 3910 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3911 for (p = 0; p < 2; ++p) { 3912 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); 3913 } 3914 #endif 3915 ++newp; 3916 /* Face H: {a, b, f} */ 3917 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3918 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3919 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3920 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3921 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3922 orntNew[2] = -2; 3923 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3924 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3925 #if defined(PETSC_USE_DEBUG) 3926 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3927 for (p = 0; p < 3; ++p) { 3928 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); 3929 } 3930 #endif 3931 supportNew[0] = (c - cStart)*8 + 1+4; 3932 supportNew[1] = (c - cStart)*8 + 2+4; 3933 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3934 #if defined(PETSC_USE_DEBUG) 3935 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3936 for (p = 0; p < 2; ++p) { 3937 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); 3938 } 3939 #endif 3940 ++newp; 3941 } 3942 /* Split Edges have 2 vertices and the same faces as the parent */ 3943 for (e = eStart; e < eEnd; ++e) { 3944 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3945 3946 for (r = 0; r < 2; ++r) { 3947 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3948 const PetscInt *cone, *ornt, *support; 3949 PetscInt coneNew[2], coneSize, c, supportSize, s; 3950 3951 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3952 coneNew[0] = vStartNew + (cone[0] - vStart); 3953 coneNew[1] = vStartNew + (cone[1] - vStart); 3954 coneNew[(r+1)%2] = newv; 3955 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3956 #if defined(PETSC_USE_DEBUG) 3957 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3958 for (p = 0; p < 2; ++p) { 3959 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); 3960 } 3961 #endif 3962 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3963 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3964 for (s = 0; s < supportSize; ++s) { 3965 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3966 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3967 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3968 for (c = 0; c < coneSize; ++c) { 3969 if (cone[c] == e) break; 3970 } 3971 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3972 } 3973 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3974 #if defined(PETSC_USE_DEBUG) 3975 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3976 for (p = 0; p < supportSize; ++p) { 3977 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); 3978 } 3979 #endif 3980 } 3981 } 3982 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3983 for (f = fStart; f < fEnd; ++f) { 3984 const PetscInt *cone, *ornt, *support; 3985 PetscInt coneSize, supportSize, s; 3986 3987 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3988 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3989 for (r = 0; r < 3; ++r) { 3990 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3991 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3992 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3993 -1, -1, 1, 6, 0, 4, 3994 2, 5, 3, 4, -1, -1, 3995 -1, -1, 3, 6, 2, 7}; 3996 3997 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3998 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3999 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4000 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4001 #if defined(PETSC_USE_DEBUG) 4002 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4003 for (p = 0; p < 2; ++p) { 4004 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); 4005 } 4006 #endif 4007 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4008 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4009 for (s = 0; s < supportSize; ++s) { 4010 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4011 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4012 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4013 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4014 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4015 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4016 if (er == eint[c]) { 4017 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4018 } else { 4019 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4020 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4021 } 4022 } 4023 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4024 #if defined(PETSC_USE_DEBUG) 4025 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4026 for (p = 0; p < intFaces; ++p) { 4027 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); 4028 } 4029 #endif 4030 } 4031 } 4032 /* Interior edges have 2 vertices and 4 faces */ 4033 for (c = cStart; c < cEnd; ++c) { 4034 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 4035 const PetscInt *cone, *ornt, *fcone; 4036 PetscInt coneNew[2], supportNew[4], find; 4037 4038 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4039 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4040 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4041 find = GetTriEdge_Static(ornt[0], 0); 4042 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4043 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4044 find = GetTriEdge_Static(ornt[2], 1); 4045 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4046 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4047 #if defined(PETSC_USE_DEBUG) 4048 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4049 for (p = 0; p < 2; ++p) { 4050 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); 4051 } 4052 #endif 4053 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 4054 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 4055 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 4056 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 4057 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4058 #if defined(PETSC_USE_DEBUG) 4059 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4060 for (p = 0; p < 4; ++p) { 4061 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); 4062 } 4063 #endif 4064 } 4065 /* Old vertices have identical supports */ 4066 for (v = vStart; v < vEnd; ++v) { 4067 const PetscInt newp = vStartNew + (v - vStart); 4068 const PetscInt *support, *cone; 4069 PetscInt size, s; 4070 4071 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4072 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4073 for (s = 0; s < size; ++s) { 4074 PetscInt r = 0; 4075 4076 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4077 if (cone[1] == v) r = 1; 4078 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4079 } 4080 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4081 #if defined(PETSC_USE_DEBUG) 4082 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4083 for (p = 0; p < size; ++p) { 4084 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); 4085 } 4086 #endif 4087 } 4088 /* Edge vertices have 2 + face*2 + 0/1 supports */ 4089 for (e = eStart; e < eEnd; ++e) { 4090 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4091 const PetscInt *cone, *support; 4092 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 4093 4094 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4095 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4096 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4097 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4098 for (s = 0; s < size; ++s) { 4099 PetscInt r = 0; 4100 4101 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4102 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4103 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4104 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4105 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4106 } 4107 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4108 for (s = 0; s < starSize*2; s += 2) { 4109 const PetscInt *cone, *ornt; 4110 PetscInt e01, e23; 4111 4112 if ((star[s] >= cStart) && (star[s] < cEnd)) { 4113 /* Check edge 0-1 */ 4114 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4115 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4116 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4117 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4118 /* Check edge 2-3 */ 4119 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4120 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4121 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4122 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4123 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 4124 } 4125 } 4126 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4127 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4128 #if defined(PETSC_USE_DEBUG) 4129 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4130 for (p = 0; p < 2+size*2+cellSize; ++p) { 4131 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); 4132 } 4133 #endif 4134 } 4135 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4136 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4137 break; 4138 case REFINER_HYBRID_SIMPLEX_3D: 4139 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4140 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 4141 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4142 for (c = cStart; c < cMax; ++c) { 4143 const PetscInt newp = cStartNew + (c - cStart)*8; 4144 const PetscInt *cone, *ornt; 4145 PetscInt coneNew[4], orntNew[4]; 4146 4147 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4148 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4149 /* A tetrahedron: {0, a, c, d} */ 4150 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 4151 orntNew[0] = ornt[0]; 4152 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 4153 orntNew[1] = ornt[1]; 4154 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 4155 orntNew[2] = ornt[2]; 4156 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4157 orntNew[3] = 0; 4158 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4159 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4160 #if defined(PETSC_USE_DEBUG) 4161 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); 4162 for (p = 0; p < 4; ++p) { 4163 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); 4164 } 4165 #endif 4166 /* B tetrahedron: {a, 1, b, e} */ 4167 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 4168 orntNew[0] = ornt[0]; 4169 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 4170 orntNew[1] = ornt[1]; 4171 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4172 orntNew[2] = 0; 4173 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 4174 orntNew[3] = ornt[3]; 4175 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4176 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4177 #if defined(PETSC_USE_DEBUG) 4178 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); 4179 for (p = 0; p < 4; ++p) { 4180 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); 4181 } 4182 #endif 4183 /* C tetrahedron: {c, b, 2, f} */ 4184 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 4185 orntNew[0] = ornt[0]; 4186 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4187 orntNew[1] = 0; 4188 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 4189 orntNew[2] = ornt[2]; 4190 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 4191 orntNew[3] = ornt[3]; 4192 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4193 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4194 #if defined(PETSC_USE_DEBUG) 4195 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); 4196 for (p = 0; p < 4; ++p) { 4197 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); 4198 } 4199 #endif 4200 /* D tetrahedron: {d, e, f, 3} */ 4201 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4202 orntNew[0] = 0; 4203 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 4204 orntNew[1] = ornt[1]; 4205 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 4206 orntNew[2] = ornt[2]; 4207 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 4208 orntNew[3] = ornt[3]; 4209 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4210 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4211 #if defined(PETSC_USE_DEBUG) 4212 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); 4213 for (p = 0; p < 4; ++p) { 4214 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); 4215 } 4216 #endif 4217 /* A' tetrahedron: {d, a, c, f} */ 4218 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4219 orntNew[0] = -3; 4220 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 4221 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 4222 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4223 orntNew[2] = 0; 4224 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4225 orntNew[3] = 2; 4226 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4227 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4228 #if defined(PETSC_USE_DEBUG) 4229 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); 4230 for (p = 0; p < 4; ++p) { 4231 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); 4232 } 4233 #endif 4234 /* B' tetrahedron: {e, b, a, f} */ 4235 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4236 orntNew[0] = -3; 4237 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4238 orntNew[1] = 1; 4239 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4240 orntNew[2] = 0; 4241 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 4242 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 4243 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4244 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4245 #if defined(PETSC_USE_DEBUG) 4246 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); 4247 for (p = 0; p < 4; ++p) { 4248 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); 4249 } 4250 #endif 4251 /* C' tetrahedron: {b, f, c, a} */ 4252 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4253 orntNew[0] = -3; 4254 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 4255 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 4256 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4257 orntNew[2] = -3; 4258 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4259 orntNew[3] = -2; 4260 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4261 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4262 #if defined(PETSC_USE_DEBUG) 4263 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); 4264 for (p = 0; p < 4; ++p) { 4265 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); 4266 } 4267 #endif 4268 /* D' tetrahedron: {f, e, d, a} */ 4269 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4270 orntNew[0] = -3; 4271 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4272 orntNew[1] = -3; 4273 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 4274 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 4275 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4276 orntNew[3] = -3; 4277 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4278 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4279 #if defined(PETSC_USE_DEBUG) 4280 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); 4281 for (p = 0; p < 4; ++p) { 4282 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); 4283 } 4284 #endif 4285 } 4286 /* Hybrid cells have 5 faces */ 4287 for (c = cMax; c < cEnd; ++c) { 4288 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 4289 const PetscInt *cone, *ornt, *fornt; 4290 PetscInt coneNew[5], orntNew[5], o, of, i; 4291 4292 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4293 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4294 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4295 o = ornt[0] < 0 ? -1 : 1; 4296 for (r = 0; r < 3; ++r) { 4297 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 4298 orntNew[0] = ornt[0]; 4299 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 4300 orntNew[1] = ornt[1]; 4301 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 4302 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 4303 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 4304 orntNew[i] = 0; 4305 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 4306 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 4307 orntNew[i] = 0; 4308 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 4309 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 4310 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); 4311 orntNew[i] = 0; 4312 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4313 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4314 #if defined(PETSC_USE_DEBUG) 4315 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); 4316 for (p = 0; p < 2; ++p) { 4317 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); 4318 } 4319 for (p = 2; p < 5; ++p) { 4320 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); 4321 } 4322 #endif 4323 } 4324 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 4325 orntNew[0] = 0; 4326 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 4327 orntNew[1] = 0; 4328 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 4329 orntNew[2] = 0; 4330 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 4331 orntNew[3] = 0; 4332 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 4333 orntNew[4] = 0; 4334 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4335 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4336 #if defined(PETSC_USE_DEBUG) 4337 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); 4338 for (p = 0; p < 2; ++p) { 4339 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); 4340 } 4341 for (p = 2; p < 5; ++p) { 4342 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); 4343 } 4344 #endif 4345 } 4346 /* Split faces have 3 edges and the same cells as the parent */ 4347 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4348 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4349 for (f = fStart; f < fMax; ++f) { 4350 const PetscInt newp = fStartNew + (f - fStart)*4; 4351 const PetscInt *cone, *ornt, *support; 4352 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 4353 4354 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4355 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4356 /* A triangle */ 4357 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4358 orntNew[0] = ornt[0]; 4359 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4360 orntNew[1] = -2; 4361 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4362 orntNew[2] = ornt[2]; 4363 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4364 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4365 #if defined(PETSC_USE_DEBUG) 4366 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); 4367 for (p = 0; p < 3; ++p) { 4368 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); 4369 } 4370 #endif 4371 /* B triangle */ 4372 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4373 orntNew[0] = ornt[0]; 4374 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4375 orntNew[1] = ornt[1]; 4376 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4377 orntNew[2] = -2; 4378 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4379 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4380 #if defined(PETSC_USE_DEBUG) 4381 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); 4382 for (p = 0; p < 3; ++p) { 4383 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); 4384 } 4385 #endif 4386 /* C triangle */ 4387 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4388 orntNew[0] = -2; 4389 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4390 orntNew[1] = ornt[1]; 4391 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4392 orntNew[2] = ornt[2]; 4393 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4394 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4395 #if defined(PETSC_USE_DEBUG) 4396 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); 4397 for (p = 0; p < 3; ++p) { 4398 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); 4399 } 4400 #endif 4401 /* D triangle */ 4402 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4403 orntNew[0] = 0; 4404 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4405 orntNew[1] = 0; 4406 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4407 orntNew[2] = 0; 4408 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4409 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4410 #if defined(PETSC_USE_DEBUG) 4411 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); 4412 for (p = 0; p < 3; ++p) { 4413 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); 4414 } 4415 #endif 4416 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4417 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4418 for (r = 0; r < 4; ++r) { 4419 for (s = 0; s < supportSize; ++s) { 4420 PetscInt subf; 4421 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4422 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4423 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4424 for (c = 0; c < coneSize; ++c) { 4425 if (cone[c] == f) break; 4426 } 4427 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4428 if (support[s] < cMax) { 4429 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 4430 } else { 4431 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 4432 } 4433 } 4434 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4435 #if defined(PETSC_USE_DEBUG) 4436 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); 4437 for (p = 0; p < supportSize; ++p) { 4438 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); 4439 } 4440 #endif 4441 } 4442 } 4443 /* Interior cell faces have 3 edges and 2 cells */ 4444 for (c = cStart; c < cMax; ++c) { 4445 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 4446 const PetscInt *cone, *ornt; 4447 PetscInt coneNew[3], orntNew[3]; 4448 PetscInt supportNew[2]; 4449 4450 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4451 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4452 /* Face A: {c, a, d} */ 4453 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4454 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4455 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4456 orntNew[1] = ornt[1] < 0 ? -2 : 0; 4457 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 4458 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4459 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4460 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4461 #if defined(PETSC_USE_DEBUG) 4462 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4463 for (p = 0; p < 3; ++p) { 4464 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); 4465 } 4466 #endif 4467 supportNew[0] = (c - cStart)*8 + 0; 4468 supportNew[1] = (c - cStart)*8 + 0+4; 4469 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4470 #if defined(PETSC_USE_DEBUG) 4471 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4472 for (p = 0; p < 2; ++p) { 4473 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); 4474 } 4475 #endif 4476 ++newp; 4477 /* Face B: {a, b, e} */ 4478 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4479 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4480 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 4481 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4482 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4483 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4484 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4485 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4486 #if defined(PETSC_USE_DEBUG) 4487 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); 4488 for (p = 0; p < 3; ++p) { 4489 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); 4490 } 4491 #endif 4492 supportNew[0] = (c - cStart)*8 + 1; 4493 supportNew[1] = (c - cStart)*8 + 1+4; 4494 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4495 #if defined(PETSC_USE_DEBUG) 4496 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4497 for (p = 0; p < 2; ++p) { 4498 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); 4499 } 4500 #endif 4501 ++newp; 4502 /* Face C: {c, f, b} */ 4503 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4504 orntNew[0] = ornt[2] < 0 ? -2 : 0; 4505 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4506 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4507 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 4508 orntNew[2] = ornt[0] < 0 ? -2 : 0; 4509 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4510 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4511 #if defined(PETSC_USE_DEBUG) 4512 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4513 for (p = 0; p < 3; ++p) { 4514 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); 4515 } 4516 #endif 4517 supportNew[0] = (c - cStart)*8 + 2; 4518 supportNew[1] = (c - cStart)*8 + 2+4; 4519 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4520 #if defined(PETSC_USE_DEBUG) 4521 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4522 for (p = 0; p < 2; ++p) { 4523 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); 4524 } 4525 #endif 4526 ++newp; 4527 /* Face D: {d, e, f} */ 4528 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 4529 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4530 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4531 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4532 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4533 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4534 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4535 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4536 #if defined(PETSC_USE_DEBUG) 4537 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4538 for (p = 0; p < 3; ++p) { 4539 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); 4540 } 4541 #endif 4542 supportNew[0] = (c - cStart)*8 + 3; 4543 supportNew[1] = (c - cStart)*8 + 3+4; 4544 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4545 #if defined(PETSC_USE_DEBUG) 4546 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4547 for (p = 0; p < 2; ++p) { 4548 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); 4549 } 4550 #endif 4551 ++newp; 4552 /* Face E: {d, f, a} */ 4553 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4554 orntNew[0] = ornt[2] < 0 ? 0 : -2; 4555 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4556 orntNew[1] = -2; 4557 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4558 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4559 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4560 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4561 #if defined(PETSC_USE_DEBUG) 4562 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4563 for (p = 0; p < 3; ++p) { 4564 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); 4565 } 4566 #endif 4567 supportNew[0] = (c - cStart)*8 + 0+4; 4568 supportNew[1] = (c - cStart)*8 + 3+4; 4569 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4570 #if defined(PETSC_USE_DEBUG) 4571 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4572 for (p = 0; p < 2; ++p) { 4573 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); 4574 } 4575 #endif 4576 ++newp; 4577 /* Face F: {c, a, f} */ 4578 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4579 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4580 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4581 orntNew[1] = 0; 4582 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4583 orntNew[2] = ornt[2] < 0 ? 0 : -2; 4584 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4585 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4586 #if defined(PETSC_USE_DEBUG) 4587 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4588 for (p = 0; p < 3; ++p) { 4589 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); 4590 } 4591 #endif 4592 supportNew[0] = (c - cStart)*8 + 0+4; 4593 supportNew[1] = (c - cStart)*8 + 2+4; 4594 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4595 #if defined(PETSC_USE_DEBUG) 4596 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4597 for (p = 0; p < 2; ++p) { 4598 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); 4599 } 4600 #endif 4601 ++newp; 4602 /* Face G: {e, a, f} */ 4603 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4604 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4605 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4606 orntNew[1] = 0; 4607 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4608 orntNew[2] = ornt[3] < 0 ? 0 : -2; 4609 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4610 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4611 #if defined(PETSC_USE_DEBUG) 4612 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4613 for (p = 0; p < 3; ++p) { 4614 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); 4615 } 4616 #endif 4617 supportNew[0] = (c - cStart)*8 + 1+4; 4618 supportNew[1] = (c - cStart)*8 + 3+4; 4619 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4620 #if defined(PETSC_USE_DEBUG) 4621 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4622 for (p = 0; p < 2; ++p) { 4623 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); 4624 } 4625 #endif 4626 ++newp; 4627 /* Face H: {a, b, f} */ 4628 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4629 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4630 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4631 orntNew[1] = ornt[3] < 0 ? 0 : -2; 4632 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4633 orntNew[2] = -2; 4634 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4635 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4636 #if defined(PETSC_USE_DEBUG) 4637 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4638 for (p = 0; p < 3; ++p) { 4639 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); 4640 } 4641 #endif 4642 supportNew[0] = (c - cStart)*8 + 1+4; 4643 supportNew[1] = (c - cStart)*8 + 2+4; 4644 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4645 #if defined(PETSC_USE_DEBUG) 4646 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4647 for (p = 0; p < 2; ++p) { 4648 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); 4649 } 4650 #endif 4651 ++newp; 4652 } 4653 /* Hybrid split faces have 4 edges and same cells */ 4654 for (f = fMax; f < fEnd; ++f) { 4655 const PetscInt *cone, *ornt, *support; 4656 PetscInt coneNew[4], orntNew[4]; 4657 PetscInt supportNew[2], size, s, c; 4658 4659 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4660 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4661 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4662 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4663 for (r = 0; r < 2; ++r) { 4664 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 4665 4666 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4667 orntNew[0] = ornt[0]; 4668 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4669 orntNew[1] = ornt[1]; 4670 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 4671 orntNew[2+r] = 0; 4672 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4673 orntNew[3-r] = 0; 4674 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4675 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4676 #if defined(PETSC_USE_DEBUG) 4677 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4678 for (p = 0; p < 2; ++p) { 4679 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); 4680 } 4681 for (p = 2; p < 4; ++p) { 4682 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); 4683 } 4684 #endif 4685 for (s = 0; s < size; ++s) { 4686 const PetscInt *coneCell, *orntCell, *fornt; 4687 PetscInt o, of; 4688 4689 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4690 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4691 o = orntCell[0] < 0 ? -1 : 1; 4692 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 4693 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 4694 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4695 of = fornt[c-2] < 0 ? -1 : 1; 4696 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 4697 } 4698 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4699 #if defined(PETSC_USE_DEBUG) 4700 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4701 for (p = 0; p < size; ++p) { 4702 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); 4703 } 4704 #endif 4705 } 4706 } 4707 /* Hybrid cell faces have 4 edges and 2 cells */ 4708 for (c = cMax; c < cEnd; ++c) { 4709 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 4710 const PetscInt *cone, *ornt; 4711 PetscInt coneNew[4], orntNew[4]; 4712 PetscInt supportNew[2]; 4713 4714 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4715 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4716 for (r = 0; r < 3; ++r) { 4717 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 4718 orntNew[0] = 0; 4719 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 4720 orntNew[1] = 0; 4721 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 4722 orntNew[2] = 0; 4723 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 4724 orntNew[3] = 0; 4725 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4726 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4727 #if defined(PETSC_USE_DEBUG) 4728 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); 4729 for (p = 0; p < 2; ++p) { 4730 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); 4731 } 4732 for (p = 2; p < 4; ++p) { 4733 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); 4734 } 4735 #endif 4736 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 4737 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 4738 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4739 #if defined(PETSC_USE_DEBUG) 4740 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); 4741 for (p = 0; p < 2; ++p) { 4742 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); 4743 } 4744 #endif 4745 } 4746 } 4747 /* Interior split edges have 2 vertices and the same faces as the parent */ 4748 for (e = eStart; e < eMax; ++e) { 4749 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4750 4751 for (r = 0; r < 2; ++r) { 4752 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4753 const PetscInt *cone, *ornt, *support; 4754 PetscInt coneNew[2], coneSize, c, supportSize, s; 4755 4756 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4757 coneNew[0] = vStartNew + (cone[0] - vStart); 4758 coneNew[1] = vStartNew + (cone[1] - vStart); 4759 coneNew[(r+1)%2] = newv; 4760 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4761 #if defined(PETSC_USE_DEBUG) 4762 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4763 for (p = 0; p < 2; ++p) { 4764 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); 4765 } 4766 #endif 4767 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4768 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4769 for (s = 0; s < supportSize; ++s) { 4770 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4771 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4772 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4773 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 4774 if (support[s] < fMax) { 4775 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4776 } else { 4777 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4778 } 4779 } 4780 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4781 #if defined(PETSC_USE_DEBUG) 4782 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4783 for (p = 0; p < supportSize; ++p) { 4784 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); 4785 } 4786 #endif 4787 } 4788 } 4789 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 4790 for (f = fStart; f < fMax; ++f) { 4791 const PetscInt *cone, *ornt, *support; 4792 PetscInt coneSize, supportSize, s; 4793 4794 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4795 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4796 for (r = 0; r < 3; ++r) { 4797 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 4798 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 4799 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 4800 -1, -1, 1, 6, 0, 4, 4801 2, 5, 3, 4, -1, -1, 4802 -1, -1, 3, 6, 2, 7}; 4803 4804 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4805 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4806 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4807 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4808 #if defined(PETSC_USE_DEBUG) 4809 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4810 for (p = 0; p < 2; ++p) { 4811 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); 4812 } 4813 #endif 4814 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4815 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4816 for (s = 0; s < supportSize; ++s) { 4817 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4818 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4819 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4820 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4821 if (support[s] < cMax) { 4822 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4823 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4824 if (er == eint[c]) { 4825 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4826 } else { 4827 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4828 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4829 } 4830 } else { 4831 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4832 } 4833 } 4834 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4835 #if defined(PETSC_USE_DEBUG) 4836 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4837 for (p = 0; p < intFaces; ++p) { 4838 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); 4839 } 4840 #endif 4841 } 4842 } 4843 /* Interior cell edges have 2 vertices and 4 faces */ 4844 for (c = cStart; c < cMax; ++c) { 4845 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4846 const PetscInt *cone, *ornt, *fcone; 4847 PetscInt coneNew[2], supportNew[4], find; 4848 4849 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4850 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4851 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4852 find = GetTriEdge_Static(ornt[0], 0); 4853 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4854 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4855 find = GetTriEdge_Static(ornt[2], 1); 4856 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4857 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4858 #if defined(PETSC_USE_DEBUG) 4859 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4860 for (p = 0; p < 2; ++p) { 4861 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); 4862 } 4863 #endif 4864 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4865 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4866 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4867 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4868 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4869 #if defined(PETSC_USE_DEBUG) 4870 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4871 for (p = 0; p < 4; ++p) { 4872 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); 4873 } 4874 #endif 4875 } 4876 /* Hybrid edges have two vertices and the same faces */ 4877 for (e = eMax; e < eEnd; ++e) { 4878 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4879 const PetscInt *cone, *support, *fcone; 4880 PetscInt coneNew[2], size, fsize, s; 4881 4882 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4883 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4884 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4885 coneNew[0] = vStartNew + (cone[0] - vStart); 4886 coneNew[1] = vStartNew + (cone[1] - vStart); 4887 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4888 #if defined(PETSC_USE_DEBUG) 4889 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4890 for (p = 0; p < 2; ++p) { 4891 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); 4892 } 4893 #endif 4894 for (s = 0; s < size; ++s) { 4895 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4896 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4897 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4898 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 4899 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4900 } 4901 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4902 #if defined(PETSC_USE_DEBUG) 4903 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4904 for (p = 0; p < size; ++p) { 4905 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); 4906 } 4907 #endif 4908 } 4909 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4910 for (f = fMax; f < fEnd; ++f) { 4911 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4912 const PetscInt *cone, *support, *ccone, *cornt; 4913 PetscInt coneNew[2], size, csize, s; 4914 4915 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4916 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4917 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4918 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4919 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4920 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4921 #if defined(PETSC_USE_DEBUG) 4922 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4923 for (p = 0; p < 2; ++p) { 4924 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); 4925 } 4926 #endif 4927 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4928 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4929 for (s = 0; s < size; ++s) { 4930 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4931 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4932 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4933 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4934 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]); 4935 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4936 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4937 } 4938 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4939 #if defined(PETSC_USE_DEBUG) 4940 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4941 for (p = 0; p < 2+size*2; ++p) { 4942 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); 4943 } 4944 #endif 4945 } 4946 /* Interior vertices have identical supports */ 4947 for (v = vStart; v < vEnd; ++v) { 4948 const PetscInt newp = vStartNew + (v - vStart); 4949 const PetscInt *support, *cone; 4950 PetscInt size, s; 4951 4952 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4953 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4954 for (s = 0; s < size; ++s) { 4955 PetscInt r = 0; 4956 4957 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4958 if (cone[1] == v) r = 1; 4959 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4960 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4961 } 4962 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4963 #if defined(PETSC_USE_DEBUG) 4964 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4965 for (p = 0; p < size; ++p) { 4966 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); 4967 } 4968 #endif 4969 } 4970 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4971 for (e = eStart; e < eMax; ++e) { 4972 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4973 const PetscInt *cone, *support; 4974 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4975 4976 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4977 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4978 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4979 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4980 for (s = 0; s < size; ++s) { 4981 PetscInt r = 0; 4982 4983 if (support[s] < fMax) { 4984 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4985 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4986 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4987 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4988 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4989 faceSize += 2; 4990 } else { 4991 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4992 ++faceSize; 4993 } 4994 } 4995 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4996 for (s = 0; s < starSize*2; s += 2) { 4997 const PetscInt *cone, *ornt; 4998 PetscInt e01, e23; 4999 5000 if ((star[s] >= cStart) && (star[s] < cMax)) { 5001 /* Check edge 0-1 */ 5002 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 5003 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 5004 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 5005 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 5006 /* Check edge 2-3 */ 5007 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 5008 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 5009 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 5010 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 5011 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 5012 } 5013 } 5014 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 5015 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5016 #if defined(PETSC_USE_DEBUG) 5017 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5018 for (p = 0; p < 2+faceSize+cellSize; ++p) { 5019 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); 5020 } 5021 #endif 5022 } 5023 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5024 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5025 break; 5026 case REFINER_SIMPLEX_TO_HEX_3D: 5027 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5028 /* All cells have 6 faces */ 5029 for (c = cStart; c < cEnd; ++c) { 5030 const PetscInt newp = cStartNew + (c - cStart)*4; 5031 const PetscInt *cone, *ornt; 5032 PetscInt coneNew[6]; 5033 PetscInt orntNew[6]; 5034 5035 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5036 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5037 /* A hex */ 5038 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5039 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5040 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5041 orntNew[1] = -4; 5042 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5043 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5044 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5045 orntNew[3] = -1; 5046 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5047 orntNew[4] = 0; 5048 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5049 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5050 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5051 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5052 #if defined(PETSC_USE_DEBUG) 5053 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); 5054 for (p = 0; p < 6; ++p) { 5055 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); 5056 } 5057 #endif 5058 /* B hex */ 5059 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5060 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5061 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5062 orntNew[1] = 0; 5063 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5064 orntNew[2] = 0; 5065 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5066 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5067 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5068 orntNew[4] = 0; 5069 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5070 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5071 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5072 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5073 #if defined(PETSC_USE_DEBUG) 5074 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); 5075 for (p = 0; p < 6; ++p) { 5076 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); 5077 } 5078 #endif 5079 /* C hex */ 5080 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5081 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5082 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5083 orntNew[1] = -4; 5084 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5085 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5086 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5087 orntNew[3] = -1; 5088 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5089 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5090 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5091 orntNew[5] = -4; 5092 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5093 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5094 #if defined(PETSC_USE_DEBUG) 5095 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); 5096 for (p = 0; p < 6; ++p) { 5097 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); 5098 } 5099 #endif 5100 /* D hex */ 5101 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5102 orntNew[0] = 0; 5103 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5104 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5105 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5106 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5107 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5108 orntNew[3] = -1; 5109 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5110 orntNew[4] = 0; 5111 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5112 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5113 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5114 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5115 #if defined(PETSC_USE_DEBUG) 5116 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); 5117 for (p = 0; p < 6; ++p) { 5118 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); 5119 } 5120 #endif 5121 } 5122 /* Split faces have 4 edges and the same cells as the parent */ 5123 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5124 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5125 for (f = fStart; f < fEnd; ++f) { 5126 const PetscInt newp = fStartNew + (f - fStart)*3; 5127 const PetscInt *cone, *ornt, *support; 5128 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5129 5130 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5131 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5132 /* A quad */ 5133 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5134 orntNew[0] = ornt[2]; 5135 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5136 orntNew[1] = ornt[0]; 5137 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5138 orntNew[2] = 0; 5139 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5140 orntNew[3] = -2; 5141 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5142 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5143 #if defined(PETSC_USE_DEBUG) 5144 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); 5145 for (p = 0; p < 4; ++p) { 5146 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); 5147 } 5148 #endif 5149 /* B quad */ 5150 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5151 orntNew[0] = ornt[0]; 5152 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5153 orntNew[1] = ornt[1]; 5154 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5155 orntNew[2] = 0; 5156 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5157 orntNew[3] = -2; 5158 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5159 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5160 #if defined(PETSC_USE_DEBUG) 5161 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); 5162 for (p = 0; p < 4; ++p) { 5163 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); 5164 } 5165 #endif 5166 /* C quad */ 5167 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5168 orntNew[0] = ornt[1]; 5169 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5170 orntNew[1] = ornt[2]; 5171 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5172 orntNew[2] = 0; 5173 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5174 orntNew[3] = -2; 5175 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5176 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5177 #if defined(PETSC_USE_DEBUG) 5178 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); 5179 for (p = 0; p < 4; ++p) { 5180 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); 5181 } 5182 #endif 5183 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5184 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5185 for (r = 0; r < 3; ++r) { 5186 for (s = 0; s < supportSize; ++s) { 5187 PetscInt subf; 5188 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5189 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5190 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5191 for (c = 0; c < coneSize; ++c) { 5192 if (cone[c] == f) break; 5193 } 5194 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5195 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5196 } 5197 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5198 #if defined(PETSC_USE_DEBUG) 5199 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); 5200 for (p = 0; p < supportSize; ++p) { 5201 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); 5202 } 5203 #endif 5204 } 5205 } 5206 /* Interior faces have 4 edges and 2 cells */ 5207 for (c = cStart; c < cEnd; ++c) { 5208 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 5209 const PetscInt *cone, *ornt; 5210 PetscInt coneNew[4], orntNew[4]; 5211 PetscInt supportNew[2]; 5212 5213 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5214 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5215 /* Face {a, g, m, h} */ 5216 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5217 orntNew[0] = 0; 5218 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5219 orntNew[1] = 0; 5220 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5221 orntNew[2] = -2; 5222 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5223 orntNew[3] = -2; 5224 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5225 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5226 #if defined(PETSC_USE_DEBUG) 5227 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5228 for (p = 0; p < 4; ++p) { 5229 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); 5230 } 5231 #endif 5232 supportNew[0] = (c - cStart)*4 + 0; 5233 supportNew[1] = (c - cStart)*4 + 1; 5234 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5235 #if defined(PETSC_USE_DEBUG) 5236 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5237 for (p = 0; p < 2; ++p) { 5238 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); 5239 } 5240 #endif 5241 ++newp; 5242 /* Face {g, b, l , m} */ 5243 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5244 orntNew[0] = -2; 5245 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5246 orntNew[1] = 0; 5247 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5248 orntNew[2] = 0; 5249 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5250 orntNew[3] = -2; 5251 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5252 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5253 #if defined(PETSC_USE_DEBUG) 5254 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5255 for (p = 0; p < 4; ++p) { 5256 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); 5257 } 5258 #endif 5259 supportNew[0] = (c - cStart)*4 + 1; 5260 supportNew[1] = (c - cStart)*4 + 2; 5261 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5262 #if defined(PETSC_USE_DEBUG) 5263 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5264 for (p = 0; p < 2; ++p) { 5265 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); 5266 } 5267 #endif 5268 ++newp; 5269 /* Face {c, g, m, i} */ 5270 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5271 orntNew[0] = 0; 5272 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5273 orntNew[1] = 0; 5274 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5275 orntNew[2] = -2; 5276 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5277 orntNew[3] = -2; 5278 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5279 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5280 #if defined(PETSC_USE_DEBUG) 5281 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5282 for (p = 0; p < 4; ++p) { 5283 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); 5284 } 5285 #endif 5286 supportNew[0] = (c - cStart)*4 + 0; 5287 supportNew[1] = (c - cStart)*4 + 2; 5288 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5289 #if defined(PETSC_USE_DEBUG) 5290 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5291 for (p = 0; p < 2; ++p) { 5292 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); 5293 } 5294 #endif 5295 ++newp; 5296 /* Face {d, h, m, i} */ 5297 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5298 orntNew[0] = 0; 5299 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5300 orntNew[1] = 0; 5301 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5302 orntNew[2] = -2; 5303 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5304 orntNew[3] = -2; 5305 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5306 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5307 #if defined(PETSC_USE_DEBUG) 5308 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5309 for (p = 0; p < 4; ++p) { 5310 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); 5311 } 5312 #endif 5313 supportNew[0] = (c - cStart)*4 + 0; 5314 supportNew[1] = (c - cStart)*4 + 3; 5315 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5316 #if defined(PETSC_USE_DEBUG) 5317 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5318 for (p = 0; p < 2; ++p) { 5319 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); 5320 } 5321 #endif 5322 ++newp; 5323 /* Face {h, m, l, e} */ 5324 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5325 orntNew[0] = 0; 5326 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5327 orntNew[1] = -2; 5328 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5329 orntNew[2] = -2; 5330 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5331 orntNew[3] = 0; 5332 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5333 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5334 #if defined(PETSC_USE_DEBUG) 5335 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5336 for (p = 0; p < 4; ++p) { 5337 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); 5338 } 5339 #endif 5340 supportNew[0] = (c - cStart)*4 + 1; 5341 supportNew[1] = (c - cStart)*4 + 3; 5342 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5343 #if defined(PETSC_USE_DEBUG) 5344 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5345 for (p = 0; p < 2; ++p) { 5346 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); 5347 } 5348 #endif 5349 ++newp; 5350 /* Face {i, m, l, f} */ 5351 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5352 orntNew[0] = 0; 5353 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5354 orntNew[1] = -2; 5355 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5356 orntNew[2] = -2; 5357 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5358 orntNew[3] = 0; 5359 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5360 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5361 #if defined(PETSC_USE_DEBUG) 5362 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5363 for (p = 0; p < 4; ++p) { 5364 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); 5365 } 5366 #endif 5367 supportNew[0] = (c - cStart)*4 + 2; 5368 supportNew[1] = (c - cStart)*4 + 3; 5369 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5370 #if defined(PETSC_USE_DEBUG) 5371 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5372 for (p = 0; p < 2; ++p) { 5373 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); 5374 } 5375 #endif 5376 ++newp; 5377 } 5378 /* Split Edges have 2 vertices and the same faces as the parent */ 5379 for (e = eStart; e < eEnd; ++e) { 5380 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5381 5382 for (r = 0; r < 2; ++r) { 5383 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5384 const PetscInt *cone, *ornt, *support; 5385 PetscInt coneNew[2], coneSize, c, supportSize, s; 5386 5387 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5388 coneNew[0] = vStartNew + (cone[0] - vStart); 5389 coneNew[1] = vStartNew + (cone[1] - vStart); 5390 coneNew[(r+1)%2] = newv; 5391 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5392 #if defined(PETSC_USE_DEBUG) 5393 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5394 for (p = 0; p < 2; ++p) { 5395 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); 5396 } 5397 #endif 5398 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5399 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5400 for (s = 0; s < supportSize; ++s) { 5401 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5402 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5403 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5404 for (c = 0; c < coneSize; ++c) { 5405 if (cone[c] == e) break; 5406 } 5407 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 5408 } 5409 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5410 #if defined(PETSC_USE_DEBUG) 5411 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5412 for (p = 0; p < supportSize; ++p) { 5413 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); 5414 } 5415 #endif 5416 } 5417 } 5418 /* Face edges have 2 vertices and 2 + cell faces supports */ 5419 for (f = fStart; f < fEnd; ++f) { 5420 const PetscInt *cone, *ornt, *support; 5421 PetscInt coneSize, supportSize, s; 5422 5423 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5424 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5425 for (r = 0; r < 3; ++r) { 5426 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 5427 PetscInt coneNew[2]; 5428 PetscInt fint[4][3] = { {0, 1, 2}, 5429 {3, 4, 0}, 5430 {2, 5, 3}, 5431 {1, 4, 5} }; 5432 5433 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5434 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5435 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 5436 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5437 #if defined(PETSC_USE_DEBUG) 5438 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5439 for (p = 0; p < 2; ++p) { 5440 if ((coneNew[p] < vStartNew) || (coneNew[p] >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", coneNew[p], vStartNew, vEndNew); 5441 } 5442 #endif 5443 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 5444 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 5445 for (s = 0; s < supportSize; ++s) { 5446 PetscInt er; 5447 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5448 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5449 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5450 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 5451 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 5452 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 5453 } 5454 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5455 #if defined(PETSC_USE_DEBUG) 5456 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5457 for (p = 0; p < supportSize + 2; ++p) { 5458 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); 5459 } 5460 #endif 5461 } 5462 } 5463 /* Interior cell edges have 2 vertices and 3 faces */ 5464 for (c = cStart; c < cEnd; ++c) { 5465 const PetscInt *cone; 5466 PetscInt fint[4][3] = { {0,1,2}, 5467 {0,3,4}, 5468 {2,3,5}, 5469 {1,4,5} } ; 5470 5471 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5472 for (r = 0; r < 4; r++) { 5473 PetscInt coneNew[2], supportNew[3]; 5474 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 5475 5476 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5477 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 5478 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5479 #if defined(PETSC_USE_DEBUG) 5480 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5481 for (p = 0; p < 2; ++p) { 5482 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); 5483 } 5484 #endif 5485 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 5486 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 5487 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 5488 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5489 #if defined(PETSC_USE_DEBUG) 5490 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5491 for (p = 0; p < 3; ++p) { 5492 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); 5493 } 5494 #endif 5495 } 5496 } 5497 /* Old vertices have identical supports */ 5498 for (v = vStart; v < vEnd; ++v) { 5499 const PetscInt newp = vStartNew + (v - vStart); 5500 const PetscInt *support, *cone; 5501 PetscInt size, s; 5502 5503 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5504 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5505 for (s = 0; s < size; ++s) { 5506 PetscInt r = 0; 5507 5508 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5509 if (cone[1] == v) r = 1; 5510 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5511 } 5512 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5513 #if defined(PETSC_USE_DEBUG) 5514 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5515 for (p = 0; p < size; ++p) { 5516 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); 5517 } 5518 #endif 5519 } 5520 /* Edge vertices have 2 + faces supports */ 5521 for (e = eStart; e < eEnd; ++e) { 5522 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5523 const PetscInt *cone, *support; 5524 PetscInt size, s; 5525 5526 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5527 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5528 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5529 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5530 for (s = 0; s < size; ++s) { 5531 PetscInt r = 0, coneSize; 5532 5533 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5534 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5535 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 5536 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 5537 } 5538 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5539 #if defined(PETSC_USE_DEBUG) 5540 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5541 for (p = 0; p < 2+size; ++p) { 5542 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); 5543 } 5544 #endif 5545 } 5546 /* Face vertices have 3 + cells supports */ 5547 for (f = fStart; f < fEnd; ++f) { 5548 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5549 const PetscInt *cone, *support; 5550 PetscInt size, s; 5551 5552 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5553 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5554 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5555 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5556 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5557 for (s = 0; s < size; ++s) { 5558 PetscInt r = 0, coneSize; 5559 5560 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5561 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5562 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 5563 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 5564 } 5565 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5566 #if defined(PETSC_USE_DEBUG) 5567 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5568 for (p = 0; p < 3+size; ++p) { 5569 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); 5570 } 5571 #endif 5572 } 5573 /* Interior cell vertices have 4 supports */ 5574 for (c = cStart; c < cEnd; ++c) { 5575 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 5576 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5577 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5578 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5579 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5580 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5581 #if defined(PETSC_USE_DEBUG) 5582 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5583 for (p = 0; p < 4; ++p) { 5584 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); 5585 } 5586 #endif 5587 } 5588 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5589 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5590 break; 5591 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 5592 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 5593 cMax = PetscMin(cEnd, cMax); 5594 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5595 fMax = PetscMin(fEnd, fMax); 5596 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5597 eMax = PetscMin(eEnd, eMax); 5598 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5599 /* All cells have 6 faces */ 5600 for (c = cStart; c < cMax; ++c) { 5601 const PetscInt newp = cStartNew + (c - cStart)*4; 5602 const PetscInt *cone, *ornt; 5603 PetscInt coneNew[6]; 5604 PetscInt orntNew[6]; 5605 5606 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5607 #if defined(PETSC_USE_DEBUG) 5608 for (p = 0; p < 4; ++p) { 5609 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); 5610 } 5611 #endif 5612 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5613 /* A hex */ 5614 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5615 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5616 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5617 orntNew[1] = -4; 5618 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5619 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5620 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5621 orntNew[3] = -1; 5622 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5623 orntNew[4] = 0; 5624 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5625 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5626 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5627 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5628 #if defined(PETSC_USE_DEBUG) 5629 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); 5630 for (p = 0; p < 6; ++p) { 5631 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); 5632 } 5633 #endif 5634 /* B hex */ 5635 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5636 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5637 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5638 orntNew[1] = 0; 5639 coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5640 orntNew[2] = 0; 5641 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5642 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5643 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5644 orntNew[4] = 0; 5645 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5646 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5647 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5648 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5649 #if defined(PETSC_USE_DEBUG) 5650 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); 5651 for (p = 0; p < 6; ++p) { 5652 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); 5653 } 5654 #endif 5655 /* C hex */ 5656 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5657 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5658 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5659 orntNew[1] = -4; 5660 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5661 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5662 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5663 orntNew[3] = -1; 5664 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5665 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5666 coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5667 orntNew[5] = -4; 5668 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5669 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5670 #if defined(PETSC_USE_DEBUG) 5671 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); 5672 for (p = 0; p < 6; ++p) { 5673 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); 5674 } 5675 #endif 5676 /* D hex */ 5677 coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5678 orntNew[0] = 0; 5679 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5680 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5681 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5682 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5683 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5684 orntNew[3] = -1; 5685 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5686 orntNew[4] = 0; 5687 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5688 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5689 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5690 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5691 #if defined(PETSC_USE_DEBUG) 5692 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); 5693 for (p = 0; p < 6; ++p) { 5694 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); 5695 } 5696 #endif 5697 } 5698 for (c = cMax; c < cEnd; ++c) { 5699 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3; 5700 const PetscInt *cone, *ornt; 5701 PetscInt coneNew[6], orntNew[6]; 5702 PetscInt o, of, cf; 5703 5704 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5705 #if defined(PETSC_USE_DEBUG) 5706 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); 5707 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); 5708 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); 5709 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); 5710 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); 5711 #endif 5712 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5713 o = ornt[0] < 0 ? -1 : 1; 5714 o = 1; 5715 /* A hex */ 5716 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5717 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5718 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */ 5719 orntNew[1] = ornt[1] < 0 ? 1 : -1; 5720 cf = 2; 5721 of = ornt[2+cf] < 0 ? -1 : 1; 5722 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */ 5723 orntNew[2] = o*of < 0 ? 0 : -1; 5724 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */ 5725 orntNew[3] = -1; 5726 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */ 5727 orntNew[4] = 0; 5728 cf = 0; 5729 of = ornt[2+cf] < 0 ? -1 : 1; 5730 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */ 5731 orntNew[5] = o*of < 0 ? 1 : -4; 5732 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5733 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5734 #if defined(PETSC_USE_DEBUG) 5735 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); 5736 for (p = 0; p < 6; ++p) { 5737 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); 5738 } 5739 #endif 5740 /* B hex */ 5741 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5742 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5743 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */ 5744 orntNew[1] = ornt[1] < 0 ? 2 : -4; 5745 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */ 5746 orntNew[2] = 0; 5747 cf = 1; 5748 of = ornt[2+cf] < 0 ? -1 : 1; 5749 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */ 5750 orntNew[3] = o*of < 0 ? 0 : -1; 5751 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */ 5752 orntNew[4] = -1; 5753 cf = 0; 5754 of = ornt[2+cf] < 0 ? -1 : 1; 5755 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */ 5756 orntNew[5] = o*of < 0 ? 1 : -4; 5757 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5758 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5759 #if defined(PETSC_USE_DEBUG) 5760 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); 5761 for (p = 0; p < 6; ++p) { 5762 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); 5763 } 5764 #endif 5765 /* C hex */ 5766 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5767 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5768 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */ 5769 orntNew[1] = ornt[1] < 0 ? 0 : -2; 5770 cf = 2; 5771 of = ornt[2+cf] < 0 ? -1 : 1; 5772 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */ 5773 orntNew[2] = o*of < 0 ? 0 : -1; 5774 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */ 5775 orntNew[3] = 0; 5776 cf = 1; 5777 of = ornt[2+cf] < 0 ? -1 : 1; 5778 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */ 5779 orntNew[4] = o*of < 0 ? 0 : -1; 5780 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */ 5781 orntNew[5] = -4; 5782 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5783 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5784 #if defined(PETSC_USE_DEBUG) 5785 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); 5786 for (p = 0; p < 6; ++p) { 5787 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); 5788 } 5789 #endif 5790 } 5791 5792 /* Split faces have 4 edges and the same cells as the parent */ 5793 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5794 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5795 for (f = fStart; f < fMax; ++f) { 5796 const PetscInt newp = fStartNew + (f - fStart)*3; 5797 const PetscInt *cone, *ornt, *support; 5798 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5799 5800 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5801 #if defined(PETSC_USE_DEBUG) 5802 for (p = 0; p < 3; ++p) { 5803 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); 5804 } 5805 #endif 5806 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5807 /* A quad */ 5808 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5809 orntNew[0] = ornt[2]; 5810 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5811 orntNew[1] = ornt[0]; 5812 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5813 orntNew[2] = 0; 5814 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5815 orntNew[3] = -2; 5816 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5817 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5818 #if defined(PETSC_USE_DEBUG) 5819 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); 5820 for (p = 0; p < 4; ++p) { 5821 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); 5822 } 5823 #endif 5824 /* B quad */ 5825 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5826 orntNew[0] = ornt[0]; 5827 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5828 orntNew[1] = ornt[1]; 5829 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5830 orntNew[2] = 0; 5831 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5832 orntNew[3] = -2; 5833 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5834 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5835 #if defined(PETSC_USE_DEBUG) 5836 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); 5837 for (p = 0; p < 4; ++p) { 5838 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); 5839 } 5840 #endif 5841 /* C quad */ 5842 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5843 orntNew[0] = ornt[1]; 5844 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5845 orntNew[1] = ornt[2]; 5846 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5847 orntNew[2] = 0; 5848 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5849 orntNew[3] = -2; 5850 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5851 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5852 #if defined(PETSC_USE_DEBUG) 5853 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); 5854 for (p = 0; p < 4; ++p) { 5855 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); 5856 } 5857 #endif 5858 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5859 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5860 for (r = 0; r < 3; ++r) { 5861 for (s = 0; s < supportSize; ++s) { 5862 PetscInt subf; 5863 5864 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5865 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); 5866 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); 5867 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5868 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5869 for (c = 0; c < coneSize; ++c) { 5870 if (cone[c] == f) break; 5871 } 5872 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5873 if (coneSize == 4) { 5874 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5875 } else if (coneSize == 5) { 5876 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); 5877 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf; 5878 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5879 } 5880 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5881 #if defined(PETSC_USE_DEBUG) 5882 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); 5883 for (p = 0; p < supportSize; ++p) { 5884 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); 5885 } 5886 #endif 5887 } 5888 } 5889 /* Interior faces have 4 edges and 2 cells */ 5890 for (c = cStart; c < cMax; ++c) { 5891 PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6; 5892 const PetscInt *cone, *ornt; 5893 PetscInt coneNew[4], orntNew[4]; 5894 PetscInt supportNew[2]; 5895 5896 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5897 #if defined(PETSC_USE_DEBUG) 5898 for (p = 0; p < 4; ++p) { 5899 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); 5900 } 5901 #endif 5902 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5903 /* Face {a, g, m, h} */ 5904 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5905 orntNew[0] = 0; 5906 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5907 orntNew[1] = 0; 5908 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5909 orntNew[2] = -2; 5910 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5911 orntNew[3] = -2; 5912 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5913 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5914 #if defined(PETSC_USE_DEBUG) 5915 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5916 for (p = 0; p < 4; ++p) { 5917 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); 5918 } 5919 #endif 5920 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5921 supportNew[1] = cStartNew + (c - cStart)*4 + 1; 5922 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5923 #if defined(PETSC_USE_DEBUG) 5924 for (p = 0; p < 2; ++p) { 5925 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); 5926 } 5927 #endif 5928 ++newp; 5929 /* Face {g, b, l , m} */ 5930 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5931 orntNew[0] = -2; 5932 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5933 orntNew[1] = 0; 5934 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5935 orntNew[2] = 0; 5936 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5937 orntNew[3] = -2; 5938 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5939 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5940 #if defined(PETSC_USE_DEBUG) 5941 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5942 for (p = 0; p < 4; ++p) { 5943 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); 5944 } 5945 #endif 5946 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5947 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5948 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5949 #if defined(PETSC_USE_DEBUG) 5950 for (p = 0; p < 2; ++p) { 5951 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); 5952 } 5953 #endif 5954 ++newp; 5955 /* Face {c, g, m, i} */ 5956 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5957 orntNew[0] = 0; 5958 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5959 orntNew[1] = 0; 5960 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5961 orntNew[2] = -2; 5962 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5963 orntNew[3] = -2; 5964 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5965 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5966 #if defined(PETSC_USE_DEBUG) 5967 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5968 for (p = 0; p < 4; ++p) { 5969 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); 5970 } 5971 #endif 5972 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5973 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5974 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5975 #if defined(PETSC_USE_DEBUG) 5976 for (p = 0; p < 2; ++p) { 5977 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); 5978 } 5979 #endif 5980 ++newp; 5981 /* Face {d, h, m, i} */ 5982 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5983 orntNew[0] = 0; 5984 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5985 orntNew[1] = 0; 5986 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5987 orntNew[2] = -2; 5988 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5989 orntNew[3] = -2; 5990 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5991 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5992 #if defined(PETSC_USE_DEBUG) 5993 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5994 for (p = 0; p < 4; ++p) { 5995 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); 5996 } 5997 #endif 5998 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5999 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6000 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6001 #if defined(PETSC_USE_DEBUG) 6002 for (p = 0; p < 2; ++p) { 6003 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); 6004 } 6005 #endif 6006 ++newp; 6007 /* Face {h, m, l, e} */ 6008 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6009 orntNew[0] = 0; 6010 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6011 orntNew[1] = -2; 6012 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 6013 orntNew[2] = -2; 6014 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6015 orntNew[3] = 0; 6016 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6017 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6018 #if defined(PETSC_USE_DEBUG) 6019 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6020 for (p = 0; p < 4; ++p) { 6021 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); 6022 } 6023 #endif 6024 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 6025 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6026 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6027 #if defined(PETSC_USE_DEBUG) 6028 for (p = 0; p < 2; ++p) { 6029 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); 6030 } 6031 #endif 6032 ++newp; 6033 /* Face {i, m, l, f} */ 6034 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6035 orntNew[0] = 0; 6036 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6037 orntNew[1] = -2; 6038 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 6039 orntNew[2] = -2; 6040 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 6041 orntNew[3] = 0; 6042 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6043 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6044 #if defined(PETSC_USE_DEBUG) 6045 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6046 for (p = 0; p < 4; ++p) { 6047 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); 6048 } 6049 #endif 6050 supportNew[0] = cStartNew + (c - cStart)*4 + 2; 6051 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6052 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6053 #if defined(PETSC_USE_DEBUG) 6054 for (p = 0; p < 2; ++p) { 6055 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); 6056 } 6057 #endif 6058 ++newp; 6059 } 6060 /* Hybrid split faces have 4 edges and same cells */ 6061 for (f = fMax; f < fEnd; ++f) { 6062 const PetscInt *cone, *ornt, *support; 6063 PetscInt coneNew[4], orntNew[4]; 6064 PetscInt size, s; 6065 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2; 6066 6067 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6068 #if defined(PETSC_USE_DEBUG) 6069 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); 6070 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); 6071 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); 6072 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); 6073 #endif 6074 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6075 /* A face */ 6076 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 6077 orntNew[0] = ornt[0]; 6078 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 6079 orntNew[1] = 0; 6080 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 6081 orntNew[2] = ornt[1] < 0 ? 0 : -2; 6082 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax); 6083 orntNew[3] = ornt[2] < 0 ? 0 : -2; 6084 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6085 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6086 #if defined(PETSC_USE_DEBUG) 6087 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6088 for (p = 0; p < 4; ++p) { 6089 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); 6090 } 6091 #endif 6092 6093 /* B face */ 6094 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 6095 orntNew[0] = ornt[0]; 6096 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax); 6097 orntNew[1] = ornt[3]; 6098 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 6099 orntNew[2] = ornt[1] < 0 ? 0 : -2; 6100 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 6101 orntNew[3] = -2; 6102 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6103 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6104 #if defined(PETSC_USE_DEBUG) 6105 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); 6106 for (p = 0; p < 4; ++p) { 6107 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); 6108 } 6109 #endif 6110 6111 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6112 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6113 for (r = 0; r < 2; ++r) { 6114 for (s = 0; s < size; ++s) { 6115 const PetscInt *coneCell, *orntCell; 6116 PetscInt coneSize, o, of, c; 6117 6118 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6119 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); 6120 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6121 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6122 o = orntCell[0] < 0 ? -1 : 1; 6123 o = 1; 6124 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 6125 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); 6126 if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 6127 of = orntCell[c] < 0 ? -1 : 1; 6128 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (c-2 + (o*of < 0 ? 1-r : r))%3; 6129 } 6130 ierr = DMPlexSetSupport(rdm, newp + r, supportRef);CHKERRQ(ierr); 6131 #if defined(PETSC_USE_DEBUG) 6132 for (p = 0; p < size; ++p) { 6133 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); 6134 } 6135 #endif 6136 } 6137 } 6138 /* Interior hybrid faces have 4 edges and 2 cells */ 6139 for (c = cMax; c < cEnd; ++c) { 6140 PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3; 6141 const PetscInt *cone, *ornt; 6142 PetscInt coneNew[4], orntNew[4]; 6143 PetscInt supportNew[2]; 6144 6145 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6146 #if defined(PETSC_USE_DEBUG) 6147 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); 6148 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); 6149 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); 6150 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); 6151 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); 6152 #endif 6153 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6154 /* Face {a, g, h, d} */ 6155 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 6156 orntNew[0] = 0; 6157 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6158 orntNew[1] = 0; 6159 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 6160 orntNew[2] = -2; 6161 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax); 6162 orntNew[3] = -2; 6163 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6164 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6165 #if defined(PETSC_USE_DEBUG) 6166 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6167 for (p = 0; p < 4; ++p) { 6168 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); 6169 } 6170 #endif 6171 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6172 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6173 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6174 #if defined(PETSC_USE_DEBUG) 6175 for (p = 0; p < 2; ++p) { 6176 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); 6177 } 6178 #endif 6179 ++newp; 6180 /* Face {b, g, h, l} */ 6181 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 6182 orntNew[0] = 0; 6183 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6184 orntNew[1] = 0; 6185 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6186 orntNew[2] = -2; 6187 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax); 6188 orntNew[3] = -2; 6189 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6190 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6191 #if defined(PETSC_USE_DEBUG) 6192 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6193 for (p = 0; p < 4; ++p) { 6194 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); 6195 } 6196 #endif 6197 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6198 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6199 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6200 #if defined(PETSC_USE_DEBUG) 6201 for (p = 0; p < 2; ++p) { 6202 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); 6203 } 6204 #endif 6205 ++newp; 6206 /* Face {c, g, h, f} */ 6207 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 6208 orntNew[0] = 0; 6209 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6210 orntNew[1] = 0; 6211 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 6212 orntNew[2] = -2; 6213 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax); 6214 orntNew[3] = -2; 6215 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6216 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6217 #if defined(PETSC_USE_DEBUG) 6218 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6219 for (p = 0; p < 4; ++p) { 6220 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); 6221 } 6222 #endif 6223 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6224 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6225 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6226 #if defined(PETSC_USE_DEBUG) 6227 for (p = 0; p < 2; ++p) { 6228 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); 6229 } 6230 #endif 6231 } 6232 /* Face edges have 2 vertices and 2 + cell faces supports */ 6233 for (f = fStart; f < fMax; ++f) { 6234 const PetscInt *cone, *ornt, *support; 6235 PetscInt coneSize, supportSize, s; 6236 6237 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6238 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6239 for (r = 0; r < 3; ++r) { 6240 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 6241 PetscInt coneNew[2]; 6242 PetscInt fint[4][3] = { {0, 1, 2}, 6243 {3, 4, 0}, 6244 {2, 5, 3}, 6245 {1, 4, 5} }; 6246 6247 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6248 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); 6249 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6250 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 6251 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6252 #if defined(PETSC_USE_DEBUG) 6253 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6254 for (p = 0; p < 2; ++p) { 6255 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); 6256 } 6257 #endif 6258 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 6259 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 6260 for (s = 0; s < supportSize; ++s) { 6261 PetscInt er; 6262 6263 supportRef[2+s] = -1; 6264 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6265 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); 6266 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); 6267 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6268 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6269 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6270 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 6271 if (coneSize == 4) { 6272 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 6273 } else if (coneSize == 5) { 6274 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); 6275 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er; 6276 } 6277 } 6278 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6279 #if defined(PETSC_USE_DEBUG) 6280 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6281 for (p = 0; p < supportSize + 2; ++p) { 6282 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); 6283 } 6284 #endif 6285 } 6286 } 6287 /* Interior cell edges have 2 vertices and 3 faces */ 6288 for (c = cStart; c < cMax; ++c) { 6289 const PetscInt *cone; 6290 PetscInt fint[4][3] = { {0,1,2}, 6291 {0,3,4}, 6292 {2,3,5}, 6293 {1,4,5} } ; 6294 6295 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6296 for (r = 0; r < 4; r++) { 6297 PetscInt coneNew[2], supportNew[3]; 6298 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 6299 6300 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); 6301 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6302 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart; 6303 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6304 #if defined(PETSC_USE_DEBUG) 6305 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6306 for (p = 0; p < 2; ++p) { 6307 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); 6308 } 6309 #endif 6310 supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0]; 6311 supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1]; 6312 supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2]; 6313 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6314 #if defined(PETSC_USE_DEBUG) 6315 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6316 for (p = 0; p < 3; ++p) { 6317 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); 6318 } 6319 #endif 6320 } 6321 } 6322 /* Hybrid edges have two vertices and the same faces */ 6323 for (e = eMax; e < eEnd; ++e) { 6324 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 6325 const PetscInt *cone, *support, *fcone; 6326 PetscInt coneNew[2], size, fsize, s; 6327 6328 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6329 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6330 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6331 coneNew[0] = vStartNew + (cone[0] - vStart); 6332 coneNew[1] = vStartNew + (cone[1] - vStart); 6333 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6334 #if defined(PETSC_USE_DEBUG) 6335 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is a edge [%D, %D)", newp, eStartNew, eEndNew); 6336 for (p = 0; p < 2; ++p) { 6337 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); 6338 } 6339 #endif 6340 for (s = 0; s < size; ++s) { 6341 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6342 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6343 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6344 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 6345 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2; 6346 } 6347 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6348 #if defined(PETSC_USE_DEBUG) 6349 for (p = 0; p < size; ++p) { 6350 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); 6351 } 6352 #endif 6353 } 6354 /* Hybrid face edges have 2 vertices and 2 + cell faces supports */ 6355 for (f = fMax; f < fEnd; ++f) { 6356 const PetscInt *cone, *ornt, *support; 6357 PetscInt coneSize, supportSize; 6358 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax; 6359 PetscInt coneNew[2], s; 6360 6361 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6362 #if defined(PETSC_USE_DEBUG) 6363 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); 6364 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); 6365 #endif 6366 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6367 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6368 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6369 #if defined(PETSC_USE_DEBUG) 6370 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6371 for (p = 0; p < 2; ++p) { 6372 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); 6373 } 6374 #endif 6375 supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0; 6376 supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1; 6377 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6378 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6379 for (s = 0; s < supportSize; ++s) { 6380 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6381 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); 6382 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6383 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6384 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6385 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); 6386 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2; 6387 } 6388 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6389 #if defined(PETSC_USE_DEBUG) 6390 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6391 for (p = 0; p < supportSize + 2; ++p) { 6392 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); 6393 } 6394 #endif 6395 } 6396 /* Hybrid cell edges have 2 vertices and 3 faces */ 6397 for (c = cMax; c < cEnd; ++c) { 6398 PetscInt coneNew[2], supportNew[3]; 6399 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6400 const PetscInt *cone; 6401 6402 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6403 #if defined(PETSC_USE_DEBUG) 6404 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); 6405 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); 6406 #endif 6407 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6408 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6409 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6410 #if defined(PETSC_USE_DEBUG) 6411 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6412 for (p = 0; p < 2; ++p) { 6413 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); 6414 } 6415 #endif 6416 supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 6417 supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 6418 supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 6419 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6420 #if defined(PETSC_USE_DEBUG) 6421 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6422 for (p = 0; p < 3; ++p) { 6423 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); 6424 } 6425 #endif 6426 } 6427 /* Old vertices have identical supports */ 6428 for (v = vStart; v < vEnd; ++v) { 6429 const PetscInt newp = vStartNew + (v - vStart); 6430 const PetscInt *support, *cone; 6431 PetscInt size, s; 6432 6433 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6434 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6435 for (s = 0; s < size; ++s) { 6436 const PetscInt e = support[s]; 6437 6438 supportRef[s] = -1; 6439 if (eStart <= e) { 6440 if (e < eMax) { 6441 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6442 supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0); 6443 } else if (e < eEnd) { 6444 supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax; 6445 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6446 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6447 } 6448 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6449 #if defined(PETSC_USE_DEBUG) 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 < size; ++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 /* Interior edge vertices have 2 + faces supports */ 6457 for (e = eStart; e < eMax; ++e) { 6458 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6459 const PetscInt *cone, *support; 6460 PetscInt size, s; 6461 6462 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6463 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6464 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6465 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6466 for (s = 0; s < size; ++s) { 6467 PetscInt r, coneSize; 6468 6469 supportRef[2+s] = -1; 6470 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6471 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); 6472 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); 6473 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6474 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 6475 if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r; 6476 else if (coneSize == 4) { 6477 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); 6478 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax; 6479 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6480 } 6481 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6482 #if defined(PETSC_USE_DEBUG) 6483 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6484 for (p = 0; p < 2+size; ++p) { 6485 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); 6486 } 6487 #endif 6488 } 6489 /* Split Edges have 2 vertices and the same faces as the parent */ 6490 for (e = eStart; e < eMax; ++e) { 6491 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6492 6493 for (r = 0; r < 2; ++r) { 6494 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6495 const PetscInt *cone, *ornt, *support; 6496 PetscInt coneNew[2], coneSize, c, supportSize, s; 6497 6498 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6499 coneNew[0] = vStartNew + (cone[0] - vStart); 6500 coneNew[1] = vStartNew + (cone[1] - vStart); 6501 coneNew[(r+1)%2] = newv; 6502 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6503 #if defined(PETSC_USE_DEBUG) 6504 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6505 for (p = 0; p < 2; ++p) { 6506 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); 6507 } 6508 #endif 6509 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6510 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6511 for (s = 0; s < supportSize; ++s) { 6512 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6513 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); 6514 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); 6515 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6516 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6517 for (c = 0; c < coneSize; ++c) { 6518 if (cone[c] == e) break; 6519 } 6520 if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 6521 else if (coneSize == 4) { 6522 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); 6523 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6524 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6525 } 6526 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6527 #if defined(PETSC_USE_DEBUG) 6528 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6529 for (p = 0; p < supportSize; ++p) { 6530 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); 6531 } 6532 #endif 6533 } 6534 } 6535 /* Face vertices have 3 + cells supports */ 6536 for (f = fStart; f < fMax; ++f) { 6537 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6538 const PetscInt *cone, *support; 6539 PetscInt size, s; 6540 6541 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6542 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6543 supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 6544 supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 6545 supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 6546 for (s = 0; s < size; ++s) { 6547 PetscInt r, coneSize; 6548 6549 supportRef[3+s] = -1; 6550 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6551 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); 6552 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); 6553 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6554 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 6555 if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r; 6556 else if (coneSize == 5) { 6557 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); 6558 supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax; 6559 } 6560 } 6561 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6562 #if defined(PETSC_USE_DEBUG) 6563 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6564 for (p = 0; p < 3+size; ++p) { 6565 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); 6566 } 6567 #endif 6568 } 6569 /* Interior cell vertices have 4 supports */ 6570 for (c = cStart; c < cMax; ++c) { 6571 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 6572 6573 supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 6574 supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6575 supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6576 supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6577 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6578 #if defined(PETSC_USE_DEBUG) 6579 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6580 for (p = 0; p < 4; ++p) { 6581 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); 6582 } 6583 #endif 6584 } 6585 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6586 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 6587 break; 6588 case REFINER_HEX_3D: 6589 /* 6590 Bottom (viewed from top) Top 6591 1---------2---------2 7---------2---------6 6592 | | | | | | 6593 | B 2 C | | H 2 G | 6594 | | | | | | 6595 3----3----0----1----1 3----3----0----1----1 6596 | | | | | | 6597 | A 0 D | | E 0 F | 6598 | | | | | | 6599 0---------0---------3 4---------0---------5 6600 */ 6601 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 6602 for (c = cStart; c < cEnd; ++c) { 6603 const PetscInt newp = (c - cStart)*8; 6604 const PetscInt *cone, *ornt; 6605 PetscInt coneNew[6], orntNew[6]; 6606 6607 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6608 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6609 /* A hex */ 6610 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 6611 orntNew[0] = ornt[0]; 6612 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6613 orntNew[1] = 0; 6614 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 6615 orntNew[2] = ornt[2]; 6616 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6617 orntNew[3] = 0; 6618 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6619 orntNew[4] = 0; 6620 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 6621 orntNew[5] = ornt[5]; 6622 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 6623 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 6624 #if defined(PETSC_USE_DEBUG) 6625 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); 6626 for (p = 0; p < 6; ++p) { 6627 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); 6628 } 6629 #endif 6630 /* B hex */ 6631 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 6632 orntNew[0] = ornt[0]; 6633 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6634 orntNew[1] = 0; 6635 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6636 orntNew[2] = -1; 6637 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 6638 orntNew[3] = ornt[3]; 6639 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6640 orntNew[4] = 0; 6641 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 6642 orntNew[5] = ornt[5]; 6643 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6644 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6645 #if defined(PETSC_USE_DEBUG) 6646 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); 6647 for (p = 0; p < 6; ++p) { 6648 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); 6649 } 6650 #endif 6651 /* C hex */ 6652 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 6653 orntNew[0] = ornt[0]; 6654 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6655 orntNew[1] = 0; 6656 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6657 orntNew[2] = -1; 6658 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 6659 orntNew[3] = ornt[3]; 6660 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 6661 orntNew[4] = ornt[4]; 6662 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6663 orntNew[5] = -4; 6664 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 6665 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 6666 #if defined(PETSC_USE_DEBUG) 6667 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); 6668 for (p = 0; p < 6; ++p) { 6669 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); 6670 } 6671 #endif 6672 /* D hex */ 6673 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 6674 orntNew[0] = ornt[0]; 6675 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6676 orntNew[1] = 0; 6677 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 6678 orntNew[2] = ornt[2]; 6679 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6680 orntNew[3] = 0; 6681 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 6682 orntNew[4] = ornt[4]; 6683 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6684 orntNew[5] = -4; 6685 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 6686 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 6687 #if defined(PETSC_USE_DEBUG) 6688 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); 6689 for (p = 0; p < 6; ++p) { 6690 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); 6691 } 6692 #endif 6693 /* E hex */ 6694 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6695 orntNew[0] = -4; 6696 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 6697 orntNew[1] = ornt[1]; 6698 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 6699 orntNew[2] = ornt[2]; 6700 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6701 orntNew[3] = 0; 6702 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6703 orntNew[4] = -1; 6704 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 6705 orntNew[5] = ornt[5]; 6706 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 6707 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 6708 #if defined(PETSC_USE_DEBUG) 6709 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); 6710 for (p = 0; p < 6; ++p) { 6711 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); 6712 } 6713 #endif 6714 /* F hex */ 6715 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6716 orntNew[0] = -4; 6717 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 6718 orntNew[1] = ornt[1]; 6719 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 6720 orntNew[2] = ornt[2]; 6721 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6722 orntNew[3] = -1; 6723 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 6724 orntNew[4] = ornt[4]; 6725 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6726 orntNew[5] = 1; 6727 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 6728 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 6729 #if defined(PETSC_USE_DEBUG) 6730 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); 6731 for (p = 0; p < 6; ++p) { 6732 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); 6733 } 6734 #endif 6735 /* G hex */ 6736 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6737 orntNew[0] = -4; 6738 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 6739 orntNew[1] = ornt[1]; 6740 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6741 orntNew[2] = 0; 6742 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 6743 orntNew[3] = ornt[3]; 6744 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 6745 orntNew[4] = ornt[4]; 6746 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6747 orntNew[5] = -3; 6748 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 6749 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 6750 #if defined(PETSC_USE_DEBUG) 6751 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); 6752 for (p = 0; p < 6; ++p) { 6753 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); 6754 } 6755 #endif 6756 /* H hex */ 6757 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6758 orntNew[0] = -4; 6759 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 6760 orntNew[1] = ornt[1]; 6761 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6762 orntNew[2] = -1; 6763 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 6764 orntNew[3] = ornt[3]; 6765 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6766 orntNew[4] = 3; 6767 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 6768 orntNew[5] = ornt[5]; 6769 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 6770 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 6771 #if defined(PETSC_USE_DEBUG) 6772 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); 6773 for (p = 0; p < 6; ++p) { 6774 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); 6775 } 6776 #endif 6777 } 6778 /* Split faces have 4 edges and the same cells as the parent */ 6779 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6780 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 6781 for (f = fStart; f < fEnd; ++f) { 6782 for (r = 0; r < 4; ++r) { 6783 /* TODO: This can come from GetFaces_Internal() */ 6784 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}; 6785 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 6786 const PetscInt *cone, *ornt, *support; 6787 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 6788 6789 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6790 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6791 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 6792 orntNew[(r+3)%4] = ornt[(r+3)%4]; 6793 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 6794 orntNew[(r+0)%4] = ornt[r]; 6795 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6796 orntNew[(r+1)%4] = 0; 6797 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 6798 orntNew[(r+2)%4] = -2; 6799 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6800 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6801 #if defined(PETSC_USE_DEBUG) 6802 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6803 for (p = 0; p < 4; ++p) { 6804 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); 6805 } 6806 #endif 6807 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6808 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6809 for (s = 0; s < supportSize; ++s) { 6810 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6811 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6812 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6813 for (c = 0; c < coneSize; ++c) { 6814 if (cone[c] == f) break; 6815 } 6816 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 6817 } 6818 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6819 #if defined(PETSC_USE_DEBUG) 6820 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6821 for (p = 0; p < supportSize; ++p) { 6822 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); 6823 } 6824 #endif 6825 } 6826 } 6827 /* Interior faces have 4 edges and 2 cells */ 6828 for (c = cStart; c < cEnd; ++c) { 6829 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}; 6830 const PetscInt *cone, *ornt; 6831 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 6832 6833 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6834 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6835 /* A-D face */ 6836 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 6837 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 6838 orntNew[0] = 0; 6839 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6840 orntNew[1] = 0; 6841 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6842 orntNew[2] = -2; 6843 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 6844 orntNew[3] = -2; 6845 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6846 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6847 #if defined(PETSC_USE_DEBUG) 6848 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6849 for (p = 0; p < 4; ++p) { 6850 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); 6851 } 6852 #endif 6853 /* C-D face */ 6854 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 6855 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 6856 orntNew[0] = 0; 6857 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6858 orntNew[1] = 0; 6859 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6860 orntNew[2] = -2; 6861 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 6862 orntNew[3] = -2; 6863 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6864 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6865 #if defined(PETSC_USE_DEBUG) 6866 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6867 for (p = 0; p < 4; ++p) { 6868 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); 6869 } 6870 #endif 6871 /* B-C face */ 6872 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 6873 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 6874 orntNew[0] = -2; 6875 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 6876 orntNew[1] = 0; 6877 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6878 orntNew[2] = 0; 6879 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6880 orntNew[3] = -2; 6881 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6882 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6883 #if defined(PETSC_USE_DEBUG) 6884 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6885 for (p = 0; p < 4; ++p) { 6886 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); 6887 } 6888 #endif 6889 /* A-B face */ 6890 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 6891 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 6892 orntNew[0] = -2; 6893 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 6894 orntNew[1] = 0; 6895 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6896 orntNew[2] = 0; 6897 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6898 orntNew[3] = -2; 6899 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6900 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6901 #if defined(PETSC_USE_DEBUG) 6902 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6903 for (p = 0; p < 4; ++p) { 6904 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); 6905 } 6906 #endif 6907 /* E-F face */ 6908 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 6909 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6910 orntNew[0] = -2; 6911 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 6912 orntNew[1] = -2; 6913 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 6914 orntNew[2] = 0; 6915 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6916 orntNew[3] = 0; 6917 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6918 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6919 #if defined(PETSC_USE_DEBUG) 6920 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6921 for (p = 0; p < 4; ++p) { 6922 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); 6923 } 6924 #endif 6925 /* F-G face */ 6926 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 6927 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6928 orntNew[0] = -2; 6929 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 6930 orntNew[1] = -2; 6931 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 6932 orntNew[2] = 0; 6933 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6934 orntNew[3] = 0; 6935 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6936 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6937 #if defined(PETSC_USE_DEBUG) 6938 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6939 for (p = 0; p < 4; ++p) { 6940 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); 6941 } 6942 #endif 6943 /* G-H face */ 6944 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 6945 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 6946 orntNew[0] = -2; 6947 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 6948 orntNew[1] = 0; 6949 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6950 orntNew[2] = 0; 6951 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6952 orntNew[3] = -2; 6953 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6954 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6955 #if defined(PETSC_USE_DEBUG) 6956 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6957 for (p = 0; p < 4; ++p) { 6958 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); 6959 } 6960 #endif 6961 /* E-H face */ 6962 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 6963 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6964 orntNew[0] = -2; 6965 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 6966 orntNew[1] = -2; 6967 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 6968 orntNew[2] = 0; 6969 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6970 orntNew[3] = 0; 6971 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6972 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6973 #if defined(PETSC_USE_DEBUG) 6974 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6975 for (p = 0; p < 4; ++p) { 6976 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); 6977 } 6978 #endif 6979 /* A-E face */ 6980 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 6981 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 6982 orntNew[0] = 0; 6983 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6984 orntNew[1] = 0; 6985 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6986 orntNew[2] = -2; 6987 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 6988 orntNew[3] = -2; 6989 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6990 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6991 #if defined(PETSC_USE_DEBUG) 6992 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6993 for (p = 0; p < 4; ++p) { 6994 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); 6995 } 6996 #endif 6997 /* D-F face */ 6998 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 6999 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7000 orntNew[0] = -2; 7001 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7002 orntNew[1] = 0; 7003 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 7004 orntNew[2] = 0; 7005 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 7006 orntNew[3] = -2; 7007 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7008 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7009 #if defined(PETSC_USE_DEBUG) 7010 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7011 for (p = 0; p < 4; ++p) { 7012 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); 7013 } 7014 #endif 7015 /* C-G face */ 7016 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 7017 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 7018 orntNew[0] = -2; 7019 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7020 orntNew[1] = -2; 7021 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7022 orntNew[2] = 0; 7023 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 7024 orntNew[3] = 0; 7025 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7026 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7027 #if defined(PETSC_USE_DEBUG) 7028 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7029 for (p = 0; p < 4; ++p) { 7030 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); 7031 } 7032 #endif 7033 /* B-H face */ 7034 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 7035 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 7036 orntNew[0] = 0; 7037 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 7038 orntNew[1] = -2; 7039 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7040 orntNew[2] = -2; 7041 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7042 orntNew[3] = 0; 7043 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7044 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7045 #if defined(PETSC_USE_DEBUG) 7046 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7047 for (p = 0; p < 4; ++p) { 7048 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); 7049 } 7050 #endif 7051 for (r = 0; r < 12; ++r) { 7052 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 7053 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7054 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7055 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7056 #if defined(PETSC_USE_DEBUG) 7057 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7058 for (p = 0; p < 2; ++p) { 7059 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); 7060 } 7061 #endif 7062 } 7063 } 7064 /* Split edges have 2 vertices and the same faces as the parent */ 7065 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7066 for (e = eStart; e < eEnd; ++e) { 7067 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7068 7069 for (r = 0; r < 2; ++r) { 7070 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7071 const PetscInt *cone, *ornt, *support; 7072 PetscInt coneNew[2], coneSize, c, supportSize, s; 7073 7074 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7075 coneNew[0] = vStartNew + (cone[0] - vStart); 7076 coneNew[1] = vStartNew + (cone[1] - vStart); 7077 coneNew[(r+1)%2] = newv; 7078 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7079 #if defined(PETSC_USE_DEBUG) 7080 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7081 for (p = 0; p < 2; ++p) { 7082 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); 7083 } 7084 #endif 7085 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7086 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7087 for (s = 0; s < supportSize; ++s) { 7088 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7089 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7090 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7091 for (c = 0; c < coneSize; ++c) { 7092 if (cone[c] == e) break; 7093 } 7094 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 7095 } 7096 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7097 #if defined(PETSC_USE_DEBUG) 7098 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7099 for (p = 0; p < supportSize; ++p) { 7100 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); 7101 } 7102 #endif 7103 } 7104 } 7105 /* Face edges have 2 vertices and 2+cells faces */ 7106 for (f = fStart; f < fEnd; ++f) { 7107 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}; 7108 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7109 const PetscInt *cone, *coneCell, *orntCell, *support; 7110 PetscInt coneNew[2], coneSize, c, supportSize, s; 7111 7112 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7113 for (r = 0; r < 4; ++r) { 7114 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7115 7116 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7117 coneNew[1] = newv; 7118 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7119 #if defined(PETSC_USE_DEBUG) 7120 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7121 for (p = 0; p < 2; ++p) { 7122 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); 7123 } 7124 #endif 7125 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7126 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7127 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7128 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7129 for (s = 0; s < supportSize; ++s) { 7130 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7131 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7132 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7133 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7134 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7135 } 7136 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7137 #if defined(PETSC_USE_DEBUG) 7138 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7139 for (p = 0; p < 2+supportSize; ++p) { 7140 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); 7141 } 7142 #endif 7143 } 7144 } 7145 /* Cell edges have 2 vertices and 4 faces */ 7146 for (c = cStart; c < cEnd; ++c) { 7147 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}; 7148 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7149 const PetscInt *cone; 7150 PetscInt coneNew[2], supportNew[4]; 7151 7152 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7153 for (r = 0; r < 6; ++r) { 7154 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7155 7156 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 7157 coneNew[1] = newv; 7158 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7159 #if defined(PETSC_USE_DEBUG) 7160 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7161 for (p = 0; p < 2; ++p) { 7162 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); 7163 } 7164 #endif 7165 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7166 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7167 #if defined(PETSC_USE_DEBUG) 7168 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7169 for (p = 0; p < 4; ++p) { 7170 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); 7171 } 7172 #endif 7173 } 7174 } 7175 /* Old vertices have identical supports */ 7176 for (v = vStart; v < vEnd; ++v) { 7177 const PetscInt newp = vStartNew + (v - vStart); 7178 const PetscInt *support, *cone; 7179 PetscInt size, s; 7180 7181 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 7182 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 7183 for (s = 0; s < size; ++s) { 7184 PetscInt r = 0; 7185 7186 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7187 if (cone[1] == v) r = 1; 7188 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 7189 } 7190 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7191 #if defined(PETSC_USE_DEBUG) 7192 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7193 for (p = 0; p < size; ++p) { 7194 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); 7195 } 7196 #endif 7197 } 7198 /* Edge vertices have 2 + faces supports */ 7199 for (e = eStart; e < eEnd; ++e) { 7200 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 7201 const PetscInt *cone, *support; 7202 PetscInt size, s; 7203 7204 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7205 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7206 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 7207 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 7208 for (s = 0; s < size; ++s) { 7209 PetscInt r; 7210 7211 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7212 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 7213 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 7214 } 7215 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7216 #if defined(PETSC_USE_DEBUG) 7217 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7218 for (p = 0; p < 2+size; ++p) { 7219 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); 7220 } 7221 #endif 7222 } 7223 /* Face vertices have 4 + cells supports */ 7224 for (f = fStart; f < fEnd; ++f) { 7225 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7226 const PetscInt *cone, *support; 7227 PetscInt size, s; 7228 7229 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7230 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7231 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7232 for (s = 0; s < size; ++s) { 7233 PetscInt r; 7234 7235 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7236 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 7237 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 7238 } 7239 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7240 #if defined(PETSC_USE_DEBUG) 7241 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7242 for (p = 0; p < 4+size; ++p) { 7243 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); 7244 } 7245 #endif 7246 } 7247 /* Cell vertices have 6 supports */ 7248 for (c = cStart; c < cEnd; ++c) { 7249 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7250 PetscInt supportNew[6]; 7251 7252 for (r = 0; r < 6; ++r) { 7253 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7254 } 7255 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7256 } 7257 ierr = PetscFree(supportRef);CHKERRQ(ierr); 7258 break; 7259 case REFINER_HYBRID_HEX_3D: 7260 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 7261 /* 7262 Bottom (viewed from top) Top 7263 1---------2---------2 7---------2---------6 7264 | | | | | | 7265 | B 2 C | | H 2 G | 7266 | | | | | | 7267 3----3----0----1----1 3----3----0----1----1 7268 | | | | | | 7269 | A 0 D | | E 0 F | 7270 | | | | | | 7271 0---------0---------3 4---------0---------5 7272 */ 7273 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 7274 for (c = cStart; c < cMax; ++c) { 7275 const PetscInt newp = (c - cStart)*8; 7276 const PetscInt *cone, *ornt; 7277 PetscInt coneNew[6], orntNew[6]; 7278 7279 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7280 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7281 /* A hex */ 7282 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 7283 orntNew[0] = ornt[0]; 7284 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7285 orntNew[1] = 0; 7286 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 7287 orntNew[2] = ornt[2]; 7288 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7289 orntNew[3] = 0; 7290 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7291 orntNew[4] = 0; 7292 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 7293 orntNew[5] = ornt[5]; 7294 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 7295 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 7296 #if defined(PETSC_USE_DEBUG) 7297 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); 7298 for (p = 0; p < 6; ++p) { 7299 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); 7300 } 7301 #endif 7302 /* B hex */ 7303 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 7304 orntNew[0] = ornt[0]; 7305 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7306 orntNew[1] = 0; 7307 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7308 orntNew[2] = -1; 7309 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 7310 orntNew[3] = ornt[3]; 7311 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7312 orntNew[4] = 0; 7313 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 7314 orntNew[5] = ornt[5]; 7315 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 7316 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 7317 #if defined(PETSC_USE_DEBUG) 7318 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); 7319 for (p = 0; p < 6; ++p) { 7320 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); 7321 } 7322 #endif 7323 /* C hex */ 7324 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 7325 orntNew[0] = ornt[0]; 7326 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7327 orntNew[1] = 0; 7328 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7329 orntNew[2] = -1; 7330 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 7331 orntNew[3] = ornt[3]; 7332 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 7333 orntNew[4] = ornt[4]; 7334 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7335 orntNew[5] = -4; 7336 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 7337 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 7338 #if defined(PETSC_USE_DEBUG) 7339 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); 7340 for (p = 0; p < 6; ++p) { 7341 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); 7342 } 7343 #endif 7344 /* D hex */ 7345 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 7346 orntNew[0] = ornt[0]; 7347 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7348 orntNew[1] = 0; 7349 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 7350 orntNew[2] = ornt[2]; 7351 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7352 orntNew[3] = 0; 7353 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 7354 orntNew[4] = ornt[4]; 7355 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7356 orntNew[5] = -4; 7357 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 7358 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 7359 #if defined(PETSC_USE_DEBUG) 7360 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); 7361 for (p = 0; p < 6; ++p) { 7362 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); 7363 } 7364 #endif 7365 /* E hex */ 7366 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7367 orntNew[0] = -4; 7368 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 7369 orntNew[1] = ornt[1]; 7370 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 7371 orntNew[2] = ornt[2]; 7372 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7373 orntNew[3] = 0; 7374 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7375 orntNew[4] = -1; 7376 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 7377 orntNew[5] = ornt[5]; 7378 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 7379 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 7380 #if defined(PETSC_USE_DEBUG) 7381 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); 7382 for (p = 0; p < 6; ++p) { 7383 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); 7384 } 7385 #endif 7386 /* F hex */ 7387 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7388 orntNew[0] = -4; 7389 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 7390 orntNew[1] = ornt[1]; 7391 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 7392 orntNew[2] = ornt[2]; 7393 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7394 orntNew[3] = -1; 7395 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 7396 orntNew[4] = ornt[4]; 7397 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7398 orntNew[5] = 1; 7399 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 7400 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 7401 #if defined(PETSC_USE_DEBUG) 7402 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); 7403 for (p = 0; p < 6; ++p) { 7404 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); 7405 } 7406 #endif 7407 /* G hex */ 7408 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7409 orntNew[0] = -4; 7410 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 7411 orntNew[1] = ornt[1]; 7412 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7413 orntNew[2] = 0; 7414 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 7415 orntNew[3] = ornt[3]; 7416 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 7417 orntNew[4] = ornt[4]; 7418 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7419 orntNew[5] = -3; 7420 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 7421 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 7422 #if defined(PETSC_USE_DEBUG) 7423 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); 7424 for (p = 0; p < 6; ++p) { 7425 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); 7426 } 7427 #endif 7428 /* H hex */ 7429 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7430 orntNew[0] = -4; 7431 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 7432 orntNew[1] = ornt[1]; 7433 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7434 orntNew[2] = -1; 7435 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 7436 orntNew[3] = ornt[3]; 7437 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7438 orntNew[4] = 3; 7439 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 7440 orntNew[5] = ornt[5]; 7441 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 7442 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 7443 #if defined(PETSC_USE_DEBUG) 7444 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); 7445 for (p = 0; p < 6; ++p) { 7446 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); 7447 } 7448 #endif 7449 } 7450 /* Hybrid cells have 6 faces: Front, Back, Sides */ 7451 /* 7452 3---------2---------2 7453 | | | 7454 | D 2 C | 7455 | | | 7456 3----3----0----1----1 7457 | | | 7458 | A 0 B | 7459 | | | 7460 0---------0---------1 7461 */ 7462 for (c = cMax; c < cEnd; ++c) { 7463 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 7464 const PetscInt *cone, *ornt, *fornt; 7465 PetscInt coneNew[6], orntNew[6], o, of, i; 7466 7467 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7468 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7469 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 7470 o = ornt[0] < 0 ? -1 : 1; 7471 for (r = 0; r < 4; ++r) { 7472 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 7473 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 7474 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 7475 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]); 7476 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 7477 orntNew[0] = ornt[0]; 7478 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 7479 orntNew[1] = ornt[0]; 7480 of = fornt[edgeA] < 0 ? -1 : 1; 7481 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 7482 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 7483 orntNew[i] = ornt[edgeA]; 7484 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 7485 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 7486 orntNew[i] = 0; 7487 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 7488 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 7489 orntNew[i] = -2; 7490 of = fornt[edgeB] < 0 ? -1 : 1; 7491 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 7492 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 7493 orntNew[i] = ornt[edgeB]; 7494 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7495 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7496 #if defined(PETSC_USE_DEBUG) 7497 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); 7498 for (p = 0; p < 2; ++p) { 7499 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); 7500 } 7501 for (p = 2; p < 6; ++p) { 7502 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); 7503 } 7504 #endif 7505 } 7506 } 7507 /* Interior split faces have 4 edges and the same cells as the parent */ 7508 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7509 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 7510 for (f = fStart; f < fMax; ++f) { 7511 for (r = 0; r < 4; ++r) { 7512 /* TODO: This can come from GetFaces_Internal() */ 7513 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}; 7514 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 7515 const PetscInt *cone, *ornt, *support; 7516 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 7517 7518 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7519 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7520 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 7521 orntNew[(r+3)%4] = ornt[(r+3)%4]; 7522 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 7523 orntNew[(r+0)%4] = ornt[r]; 7524 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7525 orntNew[(r+1)%4] = 0; 7526 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 7527 orntNew[(r+2)%4] = -2; 7528 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7529 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7530 #if defined(PETSC_USE_DEBUG) 7531 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7532 for (p = 0; p < 4; ++p) { 7533 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); 7534 } 7535 #endif 7536 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7537 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7538 for (s = 0; s < supportSize; ++s) { 7539 PetscInt subf; 7540 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7541 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7542 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7543 for (c = 0; c < coneSize; ++c) { 7544 if (cone[c] == f) break; 7545 } 7546 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 7547 if (support[s] < cMax) { 7548 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 7549 } else { 7550 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 7551 } 7552 } 7553 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7554 #if defined(PETSC_USE_DEBUG) 7555 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7556 for (p = 0; p < supportSize; ++p) { 7557 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); 7558 } 7559 #endif 7560 } 7561 } 7562 /* Interior cell faces have 4 edges and 2 cells */ 7563 for (c = cStart; c < cMax; ++c) { 7564 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}; 7565 const PetscInt *cone, *ornt; 7566 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 7567 7568 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7569 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7570 /* A-D face */ 7571 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 7572 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 7573 orntNew[0] = 0; 7574 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7575 orntNew[1] = 0; 7576 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7577 orntNew[2] = -2; 7578 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 7579 orntNew[3] = -2; 7580 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7581 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7582 #if defined(PETSC_USE_DEBUG) 7583 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7584 for (p = 0; p < 4; ++p) { 7585 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); 7586 } 7587 #endif 7588 /* C-D face */ 7589 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 7590 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 7591 orntNew[0] = 0; 7592 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7593 orntNew[1] = 0; 7594 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7595 orntNew[2] = -2; 7596 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 7597 orntNew[3] = -2; 7598 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7599 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7600 #if defined(PETSC_USE_DEBUG) 7601 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7602 for (p = 0; p < 4; ++p) { 7603 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); 7604 } 7605 #endif 7606 /* B-C face */ 7607 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 7608 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 7609 orntNew[0] = -2; 7610 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 7611 orntNew[1] = 0; 7612 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7613 orntNew[2] = 0; 7614 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7615 orntNew[3] = -2; 7616 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7617 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7618 #if defined(PETSC_USE_DEBUG) 7619 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7620 for (p = 0; p < 4; ++p) { 7621 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); 7622 } 7623 #endif 7624 /* A-B face */ 7625 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 7626 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 7627 orntNew[0] = -2; 7628 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 7629 orntNew[1] = 0; 7630 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7631 orntNew[2] = 0; 7632 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7633 orntNew[3] = -2; 7634 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7635 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7636 #if defined(PETSC_USE_DEBUG) 7637 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7638 for (p = 0; p < 4; ++p) { 7639 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); 7640 } 7641 #endif 7642 /* E-F face */ 7643 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 7644 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7645 orntNew[0] = -2; 7646 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 7647 orntNew[1] = -2; 7648 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 7649 orntNew[2] = 0; 7650 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7651 orntNew[3] = 0; 7652 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7653 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7654 #if defined(PETSC_USE_DEBUG) 7655 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7656 for (p = 0; p < 4; ++p) { 7657 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); 7658 } 7659 #endif 7660 /* F-G face */ 7661 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 7662 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7663 orntNew[0] = -2; 7664 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 7665 orntNew[1] = -2; 7666 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 7667 orntNew[2] = 0; 7668 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7669 orntNew[3] = 0; 7670 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7671 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7672 #if defined(PETSC_USE_DEBUG) 7673 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7674 for (p = 0; p < 4; ++p) { 7675 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); 7676 } 7677 #endif 7678 /* G-H face */ 7679 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 7680 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 7681 orntNew[0] = -2; 7682 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 7683 orntNew[1] = 0; 7684 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7685 orntNew[2] = 0; 7686 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7687 orntNew[3] = -2; 7688 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7689 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7690 #if defined(PETSC_USE_DEBUG) 7691 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7692 for (p = 0; p < 4; ++p) { 7693 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); 7694 } 7695 #endif 7696 /* E-H face */ 7697 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 7698 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7699 orntNew[0] = -2; 7700 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 7701 orntNew[1] = -2; 7702 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 7703 orntNew[2] = 0; 7704 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7705 orntNew[3] = 0; 7706 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7707 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7708 #if defined(PETSC_USE_DEBUG) 7709 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7710 for (p = 0; p < 4; ++p) { 7711 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); 7712 } 7713 #endif 7714 /* A-E face */ 7715 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 7716 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 7717 orntNew[0] = 0; 7718 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7719 orntNew[1] = 0; 7720 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7721 orntNew[2] = -2; 7722 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 7723 orntNew[3] = -2; 7724 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7725 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7726 #if defined(PETSC_USE_DEBUG) 7727 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7728 for (p = 0; p < 4; ++p) { 7729 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); 7730 } 7731 #endif 7732 /* D-F face */ 7733 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 7734 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7735 orntNew[0] = -2; 7736 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7737 orntNew[1] = 0; 7738 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7739 orntNew[2] = 0; 7740 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7741 orntNew[3] = -2; 7742 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7743 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7744 #if defined(PETSC_USE_DEBUG) 7745 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7746 for (p = 0; p < 4; ++p) { 7747 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); 7748 } 7749 #endif 7750 /* C-G face */ 7751 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 7752 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7753 orntNew[0] = -2; 7754 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7755 orntNew[1] = -2; 7756 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7757 orntNew[2] = 0; 7758 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7759 orntNew[3] = 0; 7760 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7761 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7762 #if defined(PETSC_USE_DEBUG) 7763 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7764 for (p = 0; p < 4; ++p) { 7765 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); 7766 } 7767 #endif 7768 /* B-H face */ 7769 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 7770 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7771 orntNew[0] = 0; 7772 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7773 orntNew[1] = -2; 7774 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7775 orntNew[2] = -2; 7776 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7777 orntNew[3] = 0; 7778 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7779 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7780 #if defined(PETSC_USE_DEBUG) 7781 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7782 for (p = 0; p < 4; ++p) { 7783 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); 7784 } 7785 #endif 7786 for (r = 0; r < 12; ++r) { 7787 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 7788 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7789 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7790 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7791 #if defined(PETSC_USE_DEBUG) 7792 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7793 for (p = 0; p < 2; ++p) { 7794 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); 7795 } 7796 #endif 7797 } 7798 } 7799 /* Hybrid split faces have 4 edges and same cells */ 7800 for (f = fMax; f < fEnd; ++f) { 7801 const PetscInt *cone, *ornt, *support; 7802 PetscInt coneNew[4], orntNew[4]; 7803 PetscInt supportNew[2], size, s, c; 7804 7805 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7806 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7807 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7808 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7809 for (r = 0; r < 2; ++r) { 7810 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 7811 7812 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 7813 orntNew[0] = ornt[0]; 7814 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 7815 orntNew[1] = ornt[1]; 7816 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 7817 orntNew[2+r] = 0; 7818 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7819 orntNew[3-r] = 0; 7820 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7821 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7822 #if defined(PETSC_USE_DEBUG) 7823 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7824 for (p = 0; p < 2; ++p) { 7825 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); 7826 } 7827 for (p = 2; p < 4; ++p) { 7828 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); 7829 } 7830 #endif 7831 for (s = 0; s < size; ++s) { 7832 const PetscInt *coneCell, *orntCell, *fornt; 7833 PetscInt o, of; 7834 7835 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7836 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7837 o = orntCell[0] < 0 ? -1 : 1; 7838 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 7839 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 7840 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 7841 of = fornt[c-2] < 0 ? -1 : 1; 7842 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 7843 } 7844 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7845 #if defined(PETSC_USE_DEBUG) 7846 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7847 for (p = 0; p < size; ++p) { 7848 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); 7849 } 7850 #endif 7851 } 7852 } 7853 /* Hybrid cell faces have 4 edges and 2 cells */ 7854 for (c = cMax; c < cEnd; ++c) { 7855 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 7856 const PetscInt *cone, *ornt; 7857 PetscInt coneNew[4], orntNew[4]; 7858 PetscInt supportNew[2]; 7859 7860 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7861 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7862 for (r = 0; r < 4; ++r) { 7863 #if 0 7864 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 7865 orntNew[0] = 0; 7866 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 7867 orntNew[1] = 0; 7868 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 7869 orntNew[2] = 0; 7870 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7871 orntNew[3] = 0; 7872 #else 7873 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 7874 orntNew[0] = 0; 7875 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 7876 orntNew[1] = 0; 7877 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 7878 orntNew[2] = 0; 7879 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7880 orntNew[3] = 0; 7881 #endif 7882 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7883 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7884 #if defined(PETSC_USE_DEBUG) 7885 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); 7886 for (p = 0; p < 2; ++p) { 7887 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); 7888 } 7889 for (p = 2; p < 4; ++p) { 7890 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); 7891 } 7892 #endif 7893 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 7894 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 7895 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 7896 #if defined(PETSC_USE_DEBUG) 7897 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); 7898 for (p = 0; p < 2; ++p) { 7899 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); 7900 } 7901 #endif 7902 } 7903 } 7904 /* Interior split edges have 2 vertices and the same faces as the parent */ 7905 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7906 for (e = eStart; e < eMax; ++e) { 7907 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7908 7909 for (r = 0; r < 2; ++r) { 7910 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7911 const PetscInt *cone, *ornt, *support; 7912 PetscInt coneNew[2], coneSize, c, supportSize, s; 7913 7914 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7915 coneNew[0] = vStartNew + (cone[0] - vStart); 7916 coneNew[1] = vStartNew + (cone[1] - vStart); 7917 coneNew[(r+1)%2] = newv; 7918 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7919 #if defined(PETSC_USE_DEBUG) 7920 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7921 for (p = 0; p < 2; ++p) { 7922 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); 7923 } 7924 #endif 7925 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7926 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7927 for (s = 0; s < supportSize; ++s) { 7928 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7929 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7930 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7931 for (c = 0; c < coneSize; ++c) { 7932 if (cone[c] == e) break; 7933 } 7934 if (support[s] < fMax) { 7935 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 7936 } else { 7937 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 7938 } 7939 } 7940 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7941 #if defined(PETSC_USE_DEBUG) 7942 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7943 for (p = 0; p < supportSize; ++p) { 7944 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); 7945 } 7946 #endif 7947 } 7948 } 7949 /* Interior face edges have 2 vertices and 2+cells faces */ 7950 for (f = fStart; f < fMax; ++f) { 7951 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}; 7952 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 7953 const PetscInt *cone, *coneCell, *orntCell, *support; 7954 PetscInt coneNew[2], coneSize, c, supportSize, s; 7955 7956 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7957 for (r = 0; r < 4; ++r) { 7958 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7959 7960 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7961 coneNew[1] = newv; 7962 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7963 #if defined(PETSC_USE_DEBUG) 7964 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7965 for (p = 0; p < 2; ++p) { 7966 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); 7967 } 7968 #endif 7969 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7970 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7971 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7972 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7973 for (s = 0; s < supportSize; ++s) { 7974 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7975 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7976 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7977 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7978 if (support[s] < cMax) { 7979 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7980 } else { 7981 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 7982 } 7983 } 7984 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7985 #if defined(PETSC_USE_DEBUG) 7986 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7987 for (p = 0; p < 2+supportSize; ++p) { 7988 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); 7989 } 7990 #endif 7991 } 7992 } 7993 /* Interior cell edges have 2 vertices and 4 faces */ 7994 for (c = cStart; c < cMax; ++c) { 7995 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}; 7996 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 7997 const PetscInt *cone; 7998 PetscInt coneNew[2], supportNew[4]; 7999 8000 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8001 for (r = 0; r < 6; ++r) { 8002 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8003 8004 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 8005 coneNew[1] = newv; 8006 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8007 #if defined(PETSC_USE_DEBUG) 8008 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 8009 for (p = 0; p < 2; ++p) { 8010 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); 8011 } 8012 #endif 8013 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 8014 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8015 #if defined(PETSC_USE_DEBUG) 8016 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 8017 for (p = 0; p < 4; ++p) { 8018 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); 8019 } 8020 #endif 8021 } 8022 } 8023 /* Hybrid edges have two vertices and the same faces */ 8024 for (e = eMax; e < eEnd; ++e) { 8025 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 8026 const PetscInt *cone, *support, *fcone; 8027 PetscInt coneNew[2], size, fsize, s; 8028 8029 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8030 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8031 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8032 coneNew[0] = vStartNew + (cone[0] - vStart); 8033 coneNew[1] = vStartNew + (cone[1] - vStart); 8034 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8035 #if defined(PETSC_USE_DEBUG) 8036 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8037 for (p = 0; p < 2; ++p) { 8038 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); 8039 } 8040 #endif 8041 for (s = 0; s < size; ++s) { 8042 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 8043 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 8044 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 8045 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 8046 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 8047 } 8048 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8049 #if defined(PETSC_USE_DEBUG) 8050 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8051 for (p = 0; p < size; ++p) { 8052 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); 8053 } 8054 #endif 8055 } 8056 /* Hybrid face edges have 2 vertices and 2+cells faces */ 8057 for (f = fMax; f < fEnd; ++f) { 8058 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 8059 const PetscInt *cone, *support, *ccone, *cornt; 8060 PetscInt coneNew[2], size, csize, s; 8061 8062 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 8063 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8064 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8065 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 8066 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 8067 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8068 #if defined(PETSC_USE_DEBUG) 8069 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8070 for (p = 0; p < 2; ++p) { 8071 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); 8072 } 8073 #endif 8074 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 8075 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 8076 for (s = 0; s < size; ++s) { 8077 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 8078 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 8079 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 8080 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 8081 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]); 8082 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 8083 } 8084 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8085 #if defined(PETSC_USE_DEBUG) 8086 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8087 for (p = 0; p < 2+size; ++p) { 8088 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); 8089 } 8090 #endif 8091 } 8092 /* Hybrid cell edges have 2 vertices and 4 faces */ 8093 for (c = cMax; c < cEnd; ++c) { 8094 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 8095 const PetscInt *cone, *support; 8096 PetscInt coneNew[2], size; 8097 8098 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8099 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 8100 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 8101 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 8102 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 8103 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8104 #if defined(PETSC_USE_DEBUG) 8105 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8106 for (p = 0; p < 2; ++p) { 8107 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); 8108 } 8109 #endif 8110 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 8111 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 8112 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 8113 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 8114 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8115 #if defined(PETSC_USE_DEBUG) 8116 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8117 for (p = 0; p < 4; ++p) { 8118 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); 8119 } 8120 #endif 8121 } 8122 /* Interior vertices have identical supports */ 8123 for (v = vStart; v < vEnd; ++v) { 8124 const PetscInt newp = vStartNew + (v - vStart); 8125 const PetscInt *support, *cone; 8126 PetscInt size, s; 8127 8128 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 8129 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 8130 for (s = 0; s < size; ++s) { 8131 PetscInt r = 0; 8132 8133 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8134 if (cone[1] == v) r = 1; 8135 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 8136 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 8137 } 8138 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8139 #if defined(PETSC_USE_DEBUG) 8140 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8141 for (p = 0; p < size; ++p) { 8142 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); 8143 } 8144 #endif 8145 } 8146 /* Interior edge vertices have 2 + faces supports */ 8147 for (e = eStart; e < eMax; ++e) { 8148 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 8149 const PetscInt *cone, *support; 8150 PetscInt size, s; 8151 8152 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8153 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8154 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 8155 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 8156 for (s = 0; s < size; ++s) { 8157 PetscInt r; 8158 8159 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8160 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 8161 if (support[s] < fMax) { 8162 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 8163 } else { 8164 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 8165 } 8166 } 8167 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8168 #if defined(PETSC_USE_DEBUG) 8169 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8170 for (p = 0; p < 2+size; ++p) { 8171 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); 8172 } 8173 #endif 8174 } 8175 /* Interior face vertices have 4 + cells supports */ 8176 for (f = fStart; f < fMax; ++f) { 8177 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8178 const PetscInt *cone, *support; 8179 PetscInt size, s; 8180 8181 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8182 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8183 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 8184 for (s = 0; s < size; ++s) { 8185 PetscInt r; 8186 8187 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8188 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 8189 if (support[s] < cMax) { 8190 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 8191 } else { 8192 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 8193 } 8194 } 8195 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8196 #if defined(PETSC_USE_DEBUG) 8197 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8198 for (p = 0; p < 4+size; ++p) { 8199 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); 8200 } 8201 #endif 8202 } 8203 /* Cell vertices have 6 supports */ 8204 for (c = cStart; c < cMax; ++c) { 8205 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 8206 PetscInt supportNew[6]; 8207 8208 for (r = 0; r < 6; ++r) { 8209 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8210 } 8211 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8212 } 8213 ierr = PetscFree(supportRef);CHKERRQ(ierr); 8214 break; 8215 default: 8216 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8217 } 8218 PetscFunctionReturn(0); 8219 } 8220 8221 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8222 { 8223 PetscSection coordSection, coordSectionNew; 8224 Vec coordinates, coordinatesNew; 8225 PetscScalar *coords, *coordsNew; 8226 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 8227 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 8228 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 8229 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 8230 VecType vtype; 8231 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 8232 const PetscReal *maxCell, *L; 8233 const DMBoundaryType *bd; 8234 PetscErrorCode ierr; 8235 8236 PetscFunctionBegin; 8237 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8238 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8239 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8240 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8241 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8242 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8243 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 8244 if (cMax < 0) cMax = cEnd; 8245 if (fMax < 0) fMax = fEnd; 8246 if (eMax < 0) eMax = eEnd; 8247 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 8248 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 8249 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 8250 /* Determine if we need to localize coordinates when generating them */ 8251 if (isperiodic && !maxCell) { 8252 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 8253 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 8254 } 8255 if (isperiodic) { 8256 ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr); 8257 ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr); 8258 ierr = PetscOptionsEnd();CHKERRQ(ierr); 8259 if (localize) { 8260 ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 8261 } 8262 } 8263 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 8264 8265 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 8266 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 8267 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 8268 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 8269 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 8270 8271 if (localize) { 8272 PetscInt p, r, newp, *pi; 8273 8274 /* New coordinates will be already localized on the cell */ 8275 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 8276 8277 /* We need the parentId to properly localize coordinates */ 8278 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 8279 switch (refiner) { 8280 case REFINER_NOOP: 8281 break; 8282 case REFINER_SIMPLEX_1D: 8283 for (p = cStart; p < cEnd; ++p) { 8284 for (r = 0; r < 2; ++r) { 8285 newp = (p - cStart)*2 + r; 8286 pi[newp] = p; 8287 } 8288 } 8289 break; 8290 case REFINER_SIMPLEX_2D: 8291 for (p = cStart; p < cEnd; ++p) { 8292 for (r = 0; r < 4; ++r) { 8293 newp = (p - cStart)*4 + r; 8294 pi[newp] = p; 8295 } 8296 } 8297 break; 8298 case REFINER_HEX_2D: 8299 for (p = cStart; p < cEnd; ++p) { 8300 for (r = 0; r < 4; ++r) { 8301 newp = (p - cStart)*4 + r; 8302 pi[newp] = p; 8303 } 8304 } 8305 break; 8306 case REFINER_SIMPLEX_TO_HEX_2D: 8307 for (p = cStart; p < cEnd; ++p) { 8308 for (r = 0; r < 3; ++r) { 8309 newp = (p - cStart)*3 + r; 8310 pi[newp] = p; 8311 } 8312 } 8313 break; 8314 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8315 for (p = cStart; p < cMax; ++p) { 8316 for (r = 0; r < 3; ++r) { 8317 newp = (p - cStart)*3 + r; 8318 pi[newp] = p; 8319 } 8320 } 8321 for (p = cMax; p < cEnd; ++p) { 8322 for (r = 0; r < 4; ++r) { 8323 newp = (cMax - cStart)*3 + (p - cMax)*4 + r; 8324 pi[newp] = p; 8325 } 8326 } 8327 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8328 cMax = cEnd; 8329 eMax = eEnd; 8330 break; 8331 case REFINER_HYBRID_SIMPLEX_2D: 8332 for (p = cStart; p < cMax; ++p) { 8333 for (r = 0; r < 4; ++r) { 8334 newp = (p - cStart)*4 + r; 8335 pi[newp] = p; 8336 } 8337 } 8338 for (p = cMax; p < cEnd; ++p) { 8339 for (r = 0; r < 2; ++r) { 8340 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8341 pi[newp] = p; 8342 } 8343 } 8344 break; 8345 case REFINER_HYBRID_HEX_2D: 8346 for (p = cStart; p < cMax; ++p) { 8347 for (r = 0; r < 4; ++r) { 8348 newp = (p - cStart)*4 + r; 8349 pi[newp] = p; 8350 } 8351 } 8352 for (p = cMax; p < cEnd; ++p) { 8353 for (r = 0; r < 2; ++r) { 8354 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8355 pi[newp] = p; 8356 } 8357 } 8358 break; 8359 case REFINER_SIMPLEX_3D: 8360 for (p = cStart; p < cEnd; ++p) { 8361 for (r = 0; r < 8; ++r) { 8362 newp = (p - cStart)*8 + r; 8363 pi[newp] = p; 8364 } 8365 } 8366 break; 8367 case REFINER_HYBRID_SIMPLEX_3D: 8368 for (p = cStart; p < cMax; ++p) { 8369 for (r = 0; r < 8; ++r) { 8370 newp = (p - cStart)*8 + r; 8371 pi[newp] = p; 8372 } 8373 } 8374 for (p = cMax; p < cEnd; ++p) { 8375 for (r = 0; r < 4; ++r) { 8376 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8377 pi[newp] = p; 8378 } 8379 } 8380 break; 8381 case REFINER_SIMPLEX_TO_HEX_3D: 8382 for (p = cStart; p < cEnd; ++p) { 8383 for (r = 0; r < 4; ++r) { 8384 newp = (p - cStart)*4 + r; 8385 pi[newp] = p; 8386 } 8387 } 8388 break; 8389 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8390 for (p = cStart; p < cMax; ++p) { 8391 for (r = 0; r < 4; ++r) { 8392 newp = (p - cStart)*4 + r; 8393 pi[newp] = p; 8394 } 8395 } 8396 for (p = cMax; p < cEnd; ++p) { 8397 for (r = 0; r < 3; ++r) { 8398 newp = (cMax - cStart)*4 + (p - cMax)*3 + r; 8399 pi[newp] = p; 8400 } 8401 } 8402 break; 8403 case REFINER_HEX_3D: 8404 for (p = cStart; p < cEnd; ++p) { 8405 for (r = 0; r < 8; ++r) { 8406 newp = (p - cStart)*8 + r; 8407 pi[newp] = p; 8408 } 8409 } 8410 break; 8411 case REFINER_HYBRID_HEX_3D: 8412 for (p = cStart; p < cMax; ++p) { 8413 for (r = 0; r < 8; ++r) { 8414 newp = (p - cStart)*8 + r; 8415 pi[newp] = p; 8416 } 8417 } 8418 for (p = cMax; p < cEnd; ++p) { 8419 for (r = 0; r < 4; ++r) { 8420 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8421 pi[newp] = p; 8422 } 8423 } 8424 break; 8425 default: 8426 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8427 } 8428 parentId = pi; 8429 } else { 8430 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8431 if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; } 8432 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 8433 } 8434 8435 /* All vertices have the spaceDim coordinates */ 8436 if (localize) { 8437 PetscInt c; 8438 8439 for (c = cStartNew; c < cEndNew; ++c) { 8440 PetscInt *cone = NULL; 8441 PetscInt closureSize, coneSize = 0, p, pdof; 8442 8443 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 8444 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 8445 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8446 for (p = 0; p < closureSize*2; p += 2) { 8447 const PetscInt point = cone[p]; 8448 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 8449 } 8450 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8451 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 8452 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 8453 } 8454 } 8455 } 8456 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 8457 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 8458 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 8459 } 8460 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 8461 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 8462 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8463 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 8464 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 8465 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 8466 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 8467 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 8468 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 8469 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 8470 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 8471 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 8472 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8473 8474 switch (refiner) { 8475 case REFINER_NOOP: break; 8476 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8477 case REFINER_SIMPLEX_TO_HEX_3D: 8478 case REFINER_HEX_3D: 8479 case REFINER_HYBRID_HEX_3D: 8480 /* Face vertices have the average of corner coordinates */ 8481 for (f = fStart; f < fMax; ++f) { 8482 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8483 PetscInt *cone = NULL; 8484 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 8485 8486 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8487 for (p = 0; p < closureSize*2; p += 2) { 8488 const PetscInt point = cone[p]; 8489 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8490 } 8491 if (localize) { 8492 const PetscInt *support = NULL; 8493 PetscInt *rStar = NULL; 8494 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 8495 PetscBool cellfound = PETSC_FALSE; 8496 8497 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8498 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 8499 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 8500 /* Compute average of coordinates for each cell sharing the face */ 8501 for (s = 0; s < supportSize; ++s) { 8502 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 8503 PetscInt *cellCone = NULL; 8504 PetscInt cellClosureSize, cellConeSize = 0, cdof; 8505 const PetscInt cell = support[s]; 8506 PetscBool copyoff = PETSC_FALSE; 8507 8508 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8509 for (p = 0; p < cellClosureSize*2; p += 2) { 8510 const PetscInt point = cellCone[p]; 8511 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 8512 } 8513 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8514 if (!cdof) { /* the parent cell does not have localized coordinates */ 8515 cellfound = PETSC_TRUE; 8516 for (v = 0; v < coneSize; ++v) { 8517 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8518 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 8519 } 8520 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8521 } else { 8522 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8523 for (p = 0; p < coneSize; ++p) { 8524 const PetscInt tv = cone[p]; 8525 PetscInt cv, voff; 8526 PetscBool locv = PETSC_TRUE; 8527 8528 for (cv = 0; cv < cellConeSize; ++cv) { 8529 if (cellCone[cv] == tv) { 8530 ccoff[p] = spaceDim*cv + coff; 8531 break; 8532 } 8533 } 8534 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D",tv); 8535 8536 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 8537 for (d = 0; d < spaceDim; ++d) { 8538 coordsNewAux[d] += coords[ccoff[p]+d]; 8539 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 8540 } 8541 if (locv && !cellfound) { 8542 cellfound = PETSC_TRUE; 8543 copyoff = PETSC_TRUE; 8544 } 8545 } 8546 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8547 8548 /* Found a valid face for the "vertex" part of the Section (physical space) 8549 i.e., a face that has at least one corner in the physical space */ 8550 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 8551 } 8552 8553 /* Localize new coordinates on each refined cell */ 8554 for (v = 0; v < rStarSize*2; v += 2) { 8555 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 8556 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 8557 const PetscInt rcell = rStar[v]; 8558 8559 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8560 if (!rcdof) continue; 8561 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 8562 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8563 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8564 if (rcone[p] == newv) { 8565 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 8566 break; 8567 } 8568 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8569 } 8570 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8571 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8572 } 8573 } 8574 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8575 } 8576 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8577 if (!cellfound) { 8578 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 8579 needcoords = PETSC_TRUE; 8580 coneSize = 0; 8581 } 8582 } else { 8583 for (v = 0; v < coneSize; ++v) { 8584 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8585 } 8586 } 8587 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8588 if (coneSize) { 8589 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8590 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8591 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8592 } else { 8593 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8594 } 8595 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8596 } 8597 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8598 case REFINER_SIMPLEX_TO_HEX_2D: 8599 case REFINER_HEX_2D: 8600 case REFINER_HYBRID_HEX_2D: 8601 case REFINER_SIMPLEX_1D: 8602 /* Cell vertices have the average of corner coordinates */ 8603 for (c = cStart; c < cMax; ++c) { 8604 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 8605 PetscInt *cone = NULL; 8606 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 8607 8608 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8609 for (p = 0; p < closureSize*2; p += 2) { 8610 const PetscInt point = cone[p]; 8611 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8612 } 8613 if (localize) { 8614 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 8615 } 8616 if (cdof) { 8617 PetscInt coff; 8618 8619 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 8620 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 8621 } else { 8622 for (v = 0; v < coneSize; ++v) { 8623 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8624 } 8625 } 8626 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8627 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8628 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8629 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8630 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8631 8632 /* Localize new coordinates on each refined cell */ 8633 if (cdof) { 8634 PetscInt *rStar = NULL, rStarSize; 8635 8636 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8637 for (v = 0; v < rStarSize*2; v += 2) { 8638 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 8639 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 8640 8641 rc = rStar[v]; 8642 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 8643 if (!rcdof) continue; 8644 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 8645 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8646 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 8647 if (cone[p] == newv) { 8648 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 8649 break; 8650 } 8651 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 8652 } 8653 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8654 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8655 } 8656 } 8657 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8658 } 8659 } 8660 case REFINER_SIMPLEX_2D: 8661 case REFINER_HYBRID_SIMPLEX_2D: 8662 case REFINER_SIMPLEX_3D: 8663 case REFINER_HYBRID_SIMPLEX_3D: 8664 /* Edge vertices have the average of endpoint coordinates */ 8665 for (e = eStart; e < eMax; ++e) { 8666 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 8667 const PetscInt *cone; 8668 PetscInt coneSize, offA, offB, offnew, d; 8669 8670 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 8671 if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 8672 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8673 if (localize) { 8674 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 8675 PetscInt *eStar = NULL, eStarSize; 8676 PetscInt *rStar = NULL, rStarSize; 8677 PetscBool cellfound = PETSC_FALSE; 8678 8679 offA = offB = -1; 8680 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 8681 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 8682 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8683 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8684 for (v = 0; v < eStarSize*2; v += 2) { 8685 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 8686 PetscScalar coordsNewAux[3] = {0., 0., 0.}; 8687 PetscInt *cellCone = NULL; 8688 PetscInt cellClosureSize, s, cv, cdof; 8689 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 8690 const PetscInt cell = eStar[v]; 8691 8692 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8693 if (!cdof) { 8694 /* Found a valid edge for the "vertex" part of the Section */ 8695 offA = voffA; 8696 offB = voffB; 8697 cellfound = PETSC_TRUE; 8698 } else { 8699 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8700 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8701 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 8702 const PetscInt point = cellCone[s]; 8703 if ((point >= vStart) && (point < vEnd)) { 8704 if (point == cone[0]) toffA = spaceDim*cv + coff; 8705 else if (point == cone[1]) toffB = spaceDim*cv + coff; 8706 cv++; 8707 } 8708 } 8709 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8710 for (d = 0; d < spaceDim; ++d) { 8711 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 8712 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 8713 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 8714 } 8715 /* Found a valid edge for the "vertex" part of the Section */ 8716 if (!cellfound && (locvA || locvB)) { 8717 cellfound = PETSC_TRUE; 8718 offA = toffA; 8719 offB = toffB; 8720 } 8721 } 8722 8723 /* Localize new coordinates on each refined cell */ 8724 for (s = 0; s < rStarSize*2; s += 2) { 8725 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 8726 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 8727 const PetscInt rcell = rStar[s]; 8728 8729 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8730 if (!rcdof) continue; 8731 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 8732 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8733 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8734 if (rcone[p] == newv) { 8735 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 8736 break; 8737 } 8738 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8739 } 8740 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8741 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8742 } 8743 } 8744 } 8745 } 8746 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8747 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8748 if (!cellfound) { 8749 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 8750 needcoords = PETSC_TRUE; 8751 } 8752 } else { 8753 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 8754 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 8755 } 8756 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8757 if (offA != -1 && offB != -1) { 8758 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 8759 for (d = 0; d < spaceDim; ++d) { 8760 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 8761 } 8762 } else { 8763 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8764 } 8765 } 8766 /* Old vertices have the same coordinates */ 8767 for (v = vStart; v < vEnd; ++v) { 8768 const PetscInt newv = vStartNew + (v - vStart); 8769 PetscInt off, offnew, d; 8770 8771 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 8772 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8773 for (d = 0; d < spaceDim; ++d) { 8774 coordsNew[offnew+d] = coords[off+d]; 8775 } 8776 8777 /* Localize new coordinates on each refined cell */ 8778 if (localize) { 8779 PetscInt p; 8780 PetscInt *rStar = NULL, rStarSize; 8781 8782 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8783 for (p = 0; p < rStarSize*2; p += 2) { 8784 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 8785 PetscScalar ocoords[3] = {0,0,0}; /* dummy values for compiler warnings about uninitialized values */ 8786 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 8787 8788 c = rStar[p]; 8789 oc = parentId[c-cStartNew]; 8790 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 8791 if (!cdof) continue; 8792 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 8793 if (!cdof) continue; 8794 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 8795 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8796 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8797 if (cone[s] == v) { 8798 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 8799 break; 8800 } 8801 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 8802 } 8803 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D",v); 8804 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8805 8806 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 8807 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8808 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8809 if (cone[s] == newv) { 8810 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 8811 break; 8812 } 8813 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 8814 } 8815 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8816 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8817 } 8818 } 8819 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8820 } 8821 } 8822 break; 8823 default: 8824 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8825 } 8826 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 8827 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8828 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 8829 8830 /* Final reduction (if needed) if we are localizing */ 8831 if (localize) { 8832 PetscBool gred; 8833 8834 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 8835 if (gred) { 8836 DM cdm; 8837 Vec aux; 8838 PetscSF sf; 8839 const PetscScalar *lArray; 8840 PetscScalar *gArray; 8841 #if defined(PETSC_USE_COMPLEX) 8842 PetscInt i, ln, gn; 8843 PetscReal *lrArray; 8844 PetscReal *grArray; 8845 #endif 8846 8847 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 8848 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 8849 ierr = DMGetSectionSF(cdm, &sf);CHKERRQ(ierr); 8850 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8851 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 8852 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 8853 #if defined(PETSC_USE_COMPLEX) 8854 ierr = VecGetLocalSize(aux, &gn);CHKERRQ(ierr); 8855 ierr = VecGetLocalSize(coordinatesNew, &ln);CHKERRQ(ierr); 8856 ierr = PetscMalloc2(ln,&lrArray,gn,&grArray);CHKERRQ(ierr); 8857 for (i=0;i<ln;i++) lrArray[i] = PetscRealPart(lArray[i]); 8858 for (i=0;i<gn;i++) grArray[i] = PetscRealPart(gArray[i]); 8859 ierr = PetscSFReduceBegin(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8860 ierr = PetscSFReduceEnd(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8861 for (i=0;i<gn;i++) gArray[i] = grArray[i]; 8862 ierr = PetscFree2(lrArray,grArray);CHKERRQ(ierr); 8863 #else 8864 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8865 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8866 #endif 8867 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8868 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 8869 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8870 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8871 ierr = VecDestroy(&aux);CHKERRQ(ierr); 8872 } 8873 } 8874 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 8875 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 8876 ierr = PetscFree(parentId);CHKERRQ(ierr); 8877 PetscFunctionReturn(0); 8878 } 8879 8880 /*@ 8881 DMPlexCreateProcessSF - Create an SF which just has process connectivity 8882 8883 Collective on dm 8884 8885 Input Parameters: 8886 + dm - The DM 8887 - sfPoint - The PetscSF which encodes point connectivity 8888 8889 Output Parameters: 8890 + processRanks - A list of process neighbors, or NULL 8891 - sfProcess - An SF encoding the process connectivity, or NULL 8892 8893 Level: developer 8894 8895 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 8896 @*/ 8897 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 8898 { 8899 PetscInt numRoots, numLeaves, l; 8900 const PetscInt *localPoints; 8901 const PetscSFNode *remotePoints; 8902 PetscInt *localPointsNew; 8903 PetscSFNode *remotePointsNew; 8904 PetscInt *ranks, *ranksNew; 8905 PetscMPIInt size; 8906 PetscErrorCode ierr; 8907 8908 PetscFunctionBegin; 8909 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8910 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 8911 if (processRanks) {PetscValidPointer(processRanks, 3);} 8912 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 8913 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 8914 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8915 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 8916 for (l = 0; l < numLeaves; ++l) { 8917 ranks[l] = remotePoints[l].rank; 8918 } 8919 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 8920 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 8921 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 8922 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 8923 for (l = 0; l < numLeaves; ++l) { 8924 ranksNew[l] = ranks[l]; 8925 localPointsNew[l] = l; 8926 remotePointsNew[l].index = 0; 8927 remotePointsNew[l].rank = ranksNew[l]; 8928 } 8929 ierr = PetscFree(ranks);CHKERRQ(ierr); 8930 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 8931 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 8932 if (sfProcess) { 8933 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 8934 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 8935 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 8936 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 8937 } 8938 PetscFunctionReturn(0); 8939 } 8940 8941 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8942 { 8943 PetscSF sf, sfNew, sfProcess; 8944 IS processRanks; 8945 MPI_Datatype depthType; 8946 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 8947 const PetscInt *localPoints, *neighbors; 8948 const PetscSFNode *remotePoints; 8949 PetscInt *localPointsNew; 8950 PetscSFNode *remotePointsNew; 8951 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 8952 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 8953 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8954 PetscErrorCode ierr; 8955 8956 PetscFunctionBegin; 8957 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 8958 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 8959 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 8960 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %D != %D", ldepth, depth); 8961 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8962 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8963 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8964 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8965 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 8966 cMax = cMax < 0 ? cEnd : cMax; 8967 fMax = fMax < 0 ? fEnd : fMax; 8968 eMax = eMax < 0 ? eEnd : eMax; 8969 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8970 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 8971 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 8972 /* Calculate size of new SF */ 8973 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8974 if (numRoots < 0) PetscFunctionReturn(0); 8975 for (l = 0; l < numLeaves; ++l) { 8976 const PetscInt p = localPoints[l]; 8977 8978 switch (refiner) { 8979 case REFINER_SIMPLEX_1D: 8980 if ((p >= vStart) && (p < vEnd)) { 8981 /* Interior vertices stay the same */ 8982 ++numLeavesNew; 8983 } else if ((p >= cStart && p < cMax)) { 8984 /* Interior cells add new cells and interior vertices */ 8985 numLeavesNew += 2 + 1; 8986 } 8987 break; 8988 case REFINER_SIMPLEX_2D: 8989 case REFINER_HYBRID_SIMPLEX_2D: 8990 if ((p >= vStart) && (p < vEnd)) { 8991 /* Interior vertices stay the same */ 8992 ++numLeavesNew; 8993 } else if ((p >= fStart) && (p < fMax)) { 8994 /* Interior faces add new faces and vertex */ 8995 numLeavesNew += 2 + 1; 8996 } else if ((p >= fMax) && (p < fEnd)) { 8997 /* Hybrid faces stay the same */ 8998 ++numLeavesNew; 8999 } else if ((p >= cStart) && (p < cMax)) { 9000 /* Interior cells add new cells and interior faces */ 9001 numLeavesNew += 4 + 3; 9002 } else if ((p >= cMax) && (p < cEnd)) { 9003 /* Hybrid cells add new cells and hybrid face */ 9004 numLeavesNew += 2 + 1; 9005 } 9006 break; 9007 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9008 case REFINER_SIMPLEX_TO_HEX_2D: 9009 if ((p >= vStart) && (p < vEnd)) { 9010 /* Interior vertices stay the same */ 9011 ++numLeavesNew; 9012 } else if ((p >= fStart) && (p < fEnd)) { 9013 /* Interior faces add new faces and vertex */ 9014 numLeavesNew += 2 + 1; 9015 } else if ((p >= cStart) && (p < cMax)) { 9016 /* Interior cells add new cells, interior faces, and vertex */ 9017 numLeavesNew += 3 + 3 + 1; 9018 } else if ((p >= cMax) && (p < cEnd)) { 9019 /* Hybrid cells add new cells, interior faces, and vertex */ 9020 numLeavesNew += 4 + 4 + 1; 9021 } 9022 break; 9023 case REFINER_HEX_2D: 9024 case REFINER_HYBRID_HEX_2D: 9025 if ((p >= vStart) && (p < vEnd)) { 9026 /* Interior vertices stay the same */ 9027 ++numLeavesNew; 9028 } else if ((p >= fStart) && (p < fMax)) { 9029 /* Interior faces add new faces and vertex */ 9030 numLeavesNew += 2 + 1; 9031 } else if ((p >= fMax) && (p < fEnd)) { 9032 /* Hybrid faces stay the same */ 9033 ++numLeavesNew; 9034 } else if ((p >= cStart) && (p < cMax)) { 9035 /* Interior cells add new cells, interior faces, and vertex */ 9036 numLeavesNew += 4 + 4 + 1; 9037 } else if ((p >= cMax) && (p < cEnd)) { 9038 /* Hybrid cells add new cells and hybrid face */ 9039 numLeavesNew += 2 + 1; 9040 } 9041 break; 9042 case REFINER_SIMPLEX_3D: 9043 case REFINER_HYBRID_SIMPLEX_3D: 9044 if ((p >= vStart) && (p < vEnd)) { 9045 /* Interior vertices stay the same */ 9046 ++numLeavesNew; 9047 } else if ((p >= eStart) && (p < eMax)) { 9048 /* Interior edges add new edges and vertex */ 9049 numLeavesNew += 2 + 1; 9050 } else if ((p >= eMax) && (p < eEnd)) { 9051 /* Hybrid edges stay the same */ 9052 ++numLeavesNew; 9053 } else if ((p >= fStart) && (p < fMax)) { 9054 /* Interior faces add new faces and edges */ 9055 numLeavesNew += 4 + 3; 9056 } else if ((p >= fMax) && (p < fEnd)) { 9057 /* Hybrid faces add new faces and edges */ 9058 numLeavesNew += 2 + 1; 9059 } else if ((p >= cStart) && (p < cMax)) { 9060 /* Interior cells add new cells, faces, and edges */ 9061 numLeavesNew += 8 + 8 + 1; 9062 } else if ((p >= cMax) && (p < cEnd)) { 9063 /* Hybrid cells add new cells and faces */ 9064 numLeavesNew += 4 + 3; 9065 } 9066 break; 9067 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9068 case REFINER_SIMPLEX_TO_HEX_3D: 9069 if ((p >= vStart) && (p < vEnd)) { 9070 /* Interior vertices stay the same */ 9071 ++numLeavesNew; 9072 } else if ((p >= eStart) && (p < eMax)) { 9073 /* Interior edges add new edges and vertex */ 9074 numLeavesNew += 2 + 1; 9075 } else if ((p >= eMax) && (p < eEnd)) { 9076 /* Hybrid edges stay the same */ 9077 ++numLeavesNew; 9078 } else if ((p >= fStart) && (p < fMax)) { 9079 /* Interior faces add new faces, edges and a vertex */ 9080 numLeavesNew += 3 + 3 + 1; 9081 } else if ((p >= fMax) && (p < fEnd)) { 9082 /* Hybrid faces add new faces and an edge */ 9083 numLeavesNew += 2 + 1; 9084 } else if ((p >= cStart) && (p < cMax)) { 9085 /* Interior cells add new cells, faces, edges and a vertex */ 9086 numLeavesNew += 4 + 6 + 4 + 1; 9087 } else if ((p >= cMax) && (p < cEnd)) { 9088 /* Hybrid cells add new cells, faces and an edge */ 9089 numLeavesNew += 3 + 3 + 1; 9090 } 9091 break; 9092 case REFINER_HEX_3D: 9093 case REFINER_HYBRID_HEX_3D: 9094 if ((p >= vStart) && (p < vEnd)) { 9095 /* Old vertices stay the same */ 9096 ++numLeavesNew; 9097 } else if ((p >= eStart) && (p < eMax)) { 9098 /* Interior edges add new edges, and vertex */ 9099 numLeavesNew += 2 + 1; 9100 } else if ((p >= eMax) && (p < eEnd)) { 9101 /* Hybrid edges stay the same */ 9102 ++numLeavesNew; 9103 } else if ((p >= fStart) && (p < fMax)) { 9104 /* Interior faces add new faces, edges, and vertex */ 9105 numLeavesNew += 4 + 4 + 1; 9106 } else if ((p >= fMax) && (p < fEnd)) { 9107 /* Hybrid faces add new faces and edges */ 9108 numLeavesNew += 2 + 1; 9109 } else if ((p >= cStart) && (p < cMax)) { 9110 /* Interior cells add new cells, faces, edges, and vertex */ 9111 numLeavesNew += 8 + 12 + 6 + 1; 9112 } else if ((p >= cStart) && (p < cEnd)) { 9113 /* Hybrid cells add new cells, faces, and edges */ 9114 numLeavesNew += 4 + 4 + 1; 9115 } 9116 break; 9117 default: 9118 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9119 } 9120 } 9121 /* Communicate depthSizes for each remote rank */ 9122 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 9123 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 9124 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 9125 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 9126 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 9127 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 9128 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9129 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9130 for (n = 0; n < numNeighbors; ++n) { 9131 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 9132 } 9133 depthSizeOld[depth] = cMax; 9134 depthSizeOld[0] = vMax; 9135 depthSizeOld[depth-1] = fMax; 9136 depthSizeOld[1] = eMax; 9137 9138 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9139 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9140 9141 depthSizeOld[depth] = cEnd - cStart; 9142 depthSizeOld[0] = vEnd - vStart; 9143 depthSizeOld[depth-1] = fEnd - fStart; 9144 depthSizeOld[1] = eEnd - eStart; 9145 9146 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9147 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9148 for (n = 0; n < numNeighbors; ++n) { 9149 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 9150 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 9151 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]; 9152 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 9153 } 9154 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 9155 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 9156 /* Calculate new point SF */ 9157 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 9158 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 9159 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 9160 for (l = 0, m = 0; l < numLeaves; ++l) { 9161 PetscInt p = localPoints[l]; 9162 PetscInt rp = remotePoints[l].index, n; 9163 PetscMPIInt rrank = remotePoints[l].rank; 9164 9165 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 9166 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rrank); 9167 switch (refiner) { 9168 case REFINER_SIMPLEX_1D: 9169 if ((p >= vStart) && (p < vEnd)) { 9170 /* Old vertices stay the same */ 9171 localPointsNew[m] = vStartNew + (p - vStart); 9172 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9173 remotePointsNew[m].rank = rrank; 9174 ++m; 9175 } else if ((p >= cStart) && (p < cMax)) { 9176 /* Old interior cells add new cells and vertex */ 9177 for (r = 0; r < 2; ++r, ++m) { 9178 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 9179 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 9180 remotePointsNew[m].rank = rrank; 9181 } 9182 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 9183 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 9184 remotePointsNew[m].rank = rrank; 9185 ++m; 9186 } 9187 break; 9188 case REFINER_SIMPLEX_2D: 9189 case REFINER_HYBRID_SIMPLEX_2D: 9190 if ((p >= vStart) && (p < vEnd)) { 9191 /* Old vertices stay the same */ 9192 localPointsNew[m] = vStartNew + (p - vStart); 9193 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9194 remotePointsNew[m].rank = rrank; 9195 ++m; 9196 } else if ((p >= fStart) && (p < fMax)) { 9197 /* Old interior faces add new faces and vertex */ 9198 for (r = 0; r < 2; ++r, ++m) { 9199 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9200 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9201 remotePointsNew[m].rank = rrank; 9202 } 9203 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9204 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9205 remotePointsNew[m].rank = rrank; 9206 ++m; 9207 } else if ((p >= fMax) && (p < fEnd)) { 9208 /* Old hybrid faces stay the same */ 9209 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9210 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9211 remotePointsNew[m].rank = rrank; 9212 ++m; 9213 } else if ((p >= cStart) && (p < cMax)) { 9214 /* Old interior cells add new cells and interior faces */ 9215 for (r = 0; r < 4; ++r, ++m) { 9216 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9217 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9218 remotePointsNew[m].rank = rrank; 9219 } 9220 for (r = 0; r < 3; ++r, ++m) { 9221 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 9222 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 9223 remotePointsNew[m].rank = rrank; 9224 } 9225 } else if ((p >= cMax) && (p < cEnd)) { 9226 /* Old hybrid cells add new cells and hybrid face */ 9227 for (r = 0; r < 2; ++r, ++m) { 9228 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9229 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9230 remotePointsNew[m].rank = rrank; 9231 } 9232 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9233 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]); 9234 remotePointsNew[m].rank = rrank; 9235 ++m; 9236 } 9237 break; 9238 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9239 case REFINER_SIMPLEX_TO_HEX_2D: 9240 if ((p >= vStart) && (p < vEnd)) { 9241 /* Old vertices stay the same */ 9242 localPointsNew[m] = vStartNew + (p - vStart); 9243 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9244 remotePointsNew[m].rank = rrank; 9245 ++m; 9246 } else if ((p >= fStart) && (p < fEnd)) { 9247 /* Old interior faces add new faces and vertex */ 9248 for (r = 0; r < 2; ++r, ++m) { 9249 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9250 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9251 remotePointsNew[m].rank = rrank; 9252 } 9253 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9254 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9255 remotePointsNew[m].rank = rrank; 9256 ++m; 9257 } else if ((p >= cStart) && (p < cMax)) { 9258 /* Old interior cells add new cells, interior faces, and a vertex */ 9259 for (r = 0; r < 3; ++r, ++m) { 9260 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 9261 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 9262 remotePointsNew[m].rank = rrank; 9263 } 9264 for (r = 0; r < 3; ++r, ++m) { 9265 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9266 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 9267 remotePointsNew[m].rank = rrank; 9268 } 9269 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9270 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9271 remotePointsNew[m].rank = rrank; 9272 ++m; 9273 } else if ((p >= cMax) && (p < cEnd)) { 9274 /* Old interior hybrid cells add new cells, interior faces, and a vertex */ 9275 for (r = 0; r < 4; ++r, ++m) { 9276 localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9277 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9278 remotePointsNew[m].rank = rrank; 9279 } 9280 for (r = 0; r < 4; ++r, ++m) { 9281 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9282 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; 9283 remotePointsNew[m].rank = rrank; 9284 } 9285 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9286 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9287 remotePointsNew[m].rank = rrank; 9288 ++m; 9289 } 9290 break; 9291 case REFINER_HEX_2D: 9292 case REFINER_HYBRID_HEX_2D: 9293 if ((p >= vStart) && (p < vEnd)) { 9294 /* Old vertices stay the same */ 9295 localPointsNew[m] = vStartNew + (p - vStart); 9296 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9297 remotePointsNew[m].rank = rrank; 9298 ++m; 9299 } else if ((p >= fStart) && (p < fMax)) { 9300 /* Old interior faces add new faces and vertex */ 9301 for (r = 0; r < 2; ++r, ++m) { 9302 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9303 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9304 remotePointsNew[m].rank = rrank; 9305 } 9306 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9307 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9308 remotePointsNew[m].rank = rrank; 9309 ++m; 9310 } else if ((p >= fMax) && (p < fEnd)) { 9311 /* Old hybrid faces stay the same */ 9312 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9313 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9314 remotePointsNew[m].rank = rrank; 9315 ++m; 9316 } else if ((p >= cStart) && (p < cMax)) { 9317 /* Old interior cells add new cells, interior faces, and vertex */ 9318 for (r = 0; r < 4; ++r, ++m) { 9319 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9320 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9321 remotePointsNew[m].rank = rrank; 9322 } 9323 for (r = 0; r < 4; ++r, ++m) { 9324 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 9325 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 9326 remotePointsNew[m].rank = rrank; 9327 } 9328 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 9329 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 9330 remotePointsNew[m].rank = rrank; 9331 ++m; 9332 } else if ((p >= cStart) && (p < cMax)) { 9333 /* Old hybrid cells add new cells and hybrid face */ 9334 for (r = 0; r < 2; ++r, ++m) { 9335 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */ 9336 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */ 9337 remotePointsNew[m].rank = rrank; 9338 } 9339 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9340 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]); 9341 remotePointsNew[m].rank = rrank; 9342 ++m; 9343 } 9344 break; 9345 case REFINER_SIMPLEX_3D: 9346 case REFINER_HYBRID_SIMPLEX_3D: 9347 if ((p >= vStart) && (p < vEnd)) { 9348 /* Interior vertices stay the same */ 9349 localPointsNew[m] = vStartNew + (p - vStart); 9350 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9351 remotePointsNew[m].rank = rrank; 9352 ++m; 9353 } else if ((p >= eStart) && (p < eMax)) { 9354 /* Interior edges add new edges and vertex */ 9355 for (r = 0; r < 2; ++r, ++m) { 9356 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9357 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9358 remotePointsNew[m].rank = rrank; 9359 } 9360 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9361 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9362 remotePointsNew[m].rank = rrank; 9363 ++m; 9364 } else if ((p >= eMax) && (p < eEnd)) { 9365 /* Hybrid edges stay the same */ 9366 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9367 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]); 9368 remotePointsNew[m].rank = rrank; 9369 ++m; 9370 } else if ((p >= fStart) && (p < fMax)) { 9371 /* Interior faces add new faces and edges */ 9372 for (r = 0; r < 4; ++r, ++m) { 9373 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9374 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9375 remotePointsNew[m].rank = rrank; 9376 } 9377 for (r = 0; r < 3; ++r, ++m) { 9378 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9379 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9380 remotePointsNew[m].rank = rrank; 9381 } 9382 } else if ((p >= fMax) && (p < fEnd)) { 9383 /* Hybrid faces add new faces and edges */ 9384 for (r = 0; r < 2; ++r, ++m) { 9385 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9386 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; 9387 remotePointsNew[m].rank = rrank; 9388 } 9389 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 9390 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]); 9391 remotePointsNew[m].rank = rrank; 9392 ++m; 9393 } else if ((p >= cStart) && (p < cMax)) { 9394 /* Interior cells add new cells, faces, and edges */ 9395 for (r = 0; r < 8; ++r, ++m) { 9396 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9397 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9398 remotePointsNew[m].rank = rrank; 9399 } 9400 for (r = 0; r < 8; ++r, ++m) { 9401 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9402 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 9403 remotePointsNew[m].rank = rrank; 9404 } 9405 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 9406 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; 9407 remotePointsNew[m].rank = rrank; 9408 ++m; 9409 } else if ((p >= cMax) && (p < cEnd)) { 9410 /* Hybrid cells add new cells and faces */ 9411 for (r = 0; r < 4; ++r, ++m) { 9412 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9413 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9414 remotePointsNew[m].rank = rrank; 9415 } 9416 for (r = 0; r < 3; ++r, ++m) { 9417 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9418 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; 9419 remotePointsNew[m].rank = rrank; 9420 } 9421 } 9422 break; 9423 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9424 case REFINER_SIMPLEX_TO_HEX_3D: 9425 if ((p >= vStart) && (p < vEnd)) { 9426 /* Interior vertices stay the same */ 9427 localPointsNew[m] = vStartNew + (p - vStart); 9428 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9429 remotePointsNew[m].rank = rrank; 9430 ++m; 9431 } else if ((p >= eStart) && (p < eMax)) { 9432 /* Interior edges add new edges and vertex */ 9433 for (r = 0; r < 2; ++r, ++m) { 9434 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9435 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9436 remotePointsNew[m].rank = rrank; 9437 } 9438 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9439 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9440 remotePointsNew[m].rank = rrank; 9441 ++m; 9442 } else if ((p >= eMax) && (p < eEnd)) { 9443 /* Hybrid edges stay the same */ 9444 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax); 9445 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]); 9446 remotePointsNew[m].rank = rrank; 9447 ++m; 9448 } else if ((p >= fStart) && (p < fMax)) { 9449 /* Interior faces add new faces, edges and a vertex */ 9450 for (r = 0; r < 3; ++r, ++m) { 9451 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 9452 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 9453 remotePointsNew[m].rank = rrank; 9454 } 9455 for (r = 0; r < 3; ++r, ++m) { 9456 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9457 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9458 remotePointsNew[m].rank = rrank; 9459 } 9460 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9461 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9462 remotePointsNew[m].rank = rrank; 9463 ++m; 9464 } else if ((p >= fMax) && (p < fEnd)) { 9465 /* Interior hybrid faces add new faces and an edge */ 9466 for (r = 0; r < 2; ++r, ++m) { 9467 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9468 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; 9469 remotePointsNew[m].rank = rrank; 9470 } 9471 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9472 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]); 9473 remotePointsNew[m].rank = rrank; 9474 ++m; 9475 } else if ((p >= cStart) && (p < cMax)) { 9476 /* Interior cells add new cells, faces, edges, and a vertex */ 9477 for (r = 0; r < 4; ++r, ++m) { 9478 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9479 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9480 remotePointsNew[m].rank = rrank; 9481 } 9482 for (r = 0; r < 6; ++r, ++m) { 9483 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9484 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r; 9485 remotePointsNew[m].rank = rrank; 9486 } 9487 for (r = 0; r < 4; ++r, ++m) { 9488 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9489 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; 9490 remotePointsNew[m].rank = rrank; 9491 } 9492 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 9493 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]); 9494 remotePointsNew[m].rank = rrank; 9495 ++m; 9496 } else if ((p >= cMax) && (p < cEnd)) { 9497 /* Interior hybrid cells add new cells, faces and an edge */ 9498 for (r = 0; r < 3; ++r, ++m) { 9499 localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9500 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9501 remotePointsNew[m].rank = rrank; 9502 } 9503 for (r = 0; r < 3; ++r, ++m) { 9504 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9505 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; 9506 remotePointsNew[m].rank = rrank; 9507 } 9508 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9509 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]); 9510 remotePointsNew[m].rank = rrank; 9511 ++m; 9512 } 9513 break; 9514 case REFINER_HEX_3D: 9515 case REFINER_HYBRID_HEX_3D: 9516 if ((p >= vStart) && (p < vEnd)) { 9517 /* Interior vertices stay the same */ 9518 localPointsNew[m] = vStartNew + (p - vStart); 9519 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9520 remotePointsNew[m].rank = rrank; 9521 ++m; 9522 } else if ((p >= eStart) && (p < eMax)) { 9523 /* Interior edges add new edges and vertex */ 9524 for (r = 0; r < 2; ++r, ++m) { 9525 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9526 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9527 remotePointsNew[m].rank = rrank; 9528 } 9529 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9530 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9531 remotePointsNew[m].rank = rrank; 9532 ++m; 9533 } else if ((p >= eMax) && (p < eEnd)) { 9534 /* Hybrid edges stay the same */ 9535 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 9536 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]); 9537 remotePointsNew[m].rank = rrank; 9538 ++m; 9539 } else if ((p >= fStart) && (p < fMax)) { 9540 /* Interior faces add new faces, edges, and vertex */ 9541 for (r = 0; r < 4; ++r, ++m) { 9542 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9543 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9544 remotePointsNew[m].rank = rrank; 9545 } 9546 for (r = 0; r < 4; ++r, ++m) { 9547 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 9548 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 9549 remotePointsNew[m].rank = rrank; 9550 } 9551 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9552 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9553 remotePointsNew[m].rank = rrank; 9554 ++m; 9555 } else if ((p >= fMax) && (p < fEnd)) { 9556 /* Hybrid faces add new faces and edges */ 9557 for (r = 0; r < 2; ++r, ++m) { 9558 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 9559 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; 9560 remotePointsNew[m].rank = rrank; 9561 } 9562 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 9563 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]); 9564 remotePointsNew[m].rank = rrank; 9565 ++m; 9566 } else if ((p >= cStart) && (p < cMax)) { 9567 /* Interior cells add new cells, faces, edges, and vertex */ 9568 for (r = 0; r < 8; ++r, ++m) { 9569 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9570 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9571 remotePointsNew[m].rank = rrank; 9572 } 9573 for (r = 0; r < 12; ++r, ++m) { 9574 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 9575 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 9576 remotePointsNew[m].rank = rrank; 9577 } 9578 for (r = 0; r < 6; ++r, ++m) { 9579 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 9580 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; 9581 remotePointsNew[m].rank = rrank; 9582 } 9583 for (r = 0; r < 1; ++r, ++m) { 9584 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 9585 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 9586 remotePointsNew[m].rank = rrank; 9587 } 9588 } else if ((p >= cMax) && (p < cEnd)) { 9589 /* Hybrid cells add new cells, faces, and edges */ 9590 for (r = 0; r < 4; ++r, ++m) { 9591 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9592 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9593 remotePointsNew[m].rank = rrank; 9594 } 9595 for (r = 0; r < 4; ++r, ++m) { 9596 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 9597 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; 9598 remotePointsNew[m].rank = rrank; 9599 } 9600 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9601 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]); 9602 remotePointsNew[m].rank = rrank; 9603 ++m; 9604 } 9605 break; 9606 default: 9607 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9608 } 9609 } 9610 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 9611 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 9612 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 9613 { 9614 PetscSFNode *rp, *rtmp; 9615 PetscInt *lp, *idx, *ltmp, i; 9616 9617 /* SF needs sorted leaves to correct calculate Gather */ 9618 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 9619 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 9620 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 9621 for (i = 0; i < numLeavesNew; ++i) { 9622 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); 9623 idx[i] = i; 9624 } 9625 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 9626 for (i = 0; i < numLeavesNew; ++i) { 9627 lp[i] = localPointsNew[idx[i]]; 9628 rp[i] = remotePointsNew[idx[i]]; 9629 } 9630 ltmp = localPointsNew; 9631 localPointsNew = lp; 9632 rtmp = remotePointsNew; 9633 remotePointsNew = rp; 9634 ierr = PetscFree(idx);CHKERRQ(ierr); 9635 ierr = PetscFree(ltmp);CHKERRQ(ierr); 9636 ierr = PetscFree(rtmp);CHKERRQ(ierr); 9637 } 9638 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 9639 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 9640 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 9641 PetscFunctionReturn(0); 9642 } 9643 9644 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 9645 { 9646 PetscInt numLabels, l; 9647 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 9648 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 9649 PetscErrorCode ierr; 9650 9651 PetscFunctionBegin; 9652 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 9653 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 9654 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9655 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 9656 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 9657 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 9658 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 9659 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 9660 switch (refiner) { 9661 case REFINER_NOOP: 9662 case REFINER_SIMPLEX_1D: 9663 case REFINER_SIMPLEX_2D: 9664 case REFINER_SIMPLEX_TO_HEX_2D: 9665 case REFINER_HEX_2D: 9666 case REFINER_SIMPLEX_3D: 9667 case REFINER_HEX_3D: 9668 case REFINER_SIMPLEX_TO_HEX_3D: 9669 break; 9670 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9671 case REFINER_HYBRID_SIMPLEX_3D: 9672 case REFINER_HYBRID_HEX_3D: 9673 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 9674 case REFINER_HYBRID_SIMPLEX_2D: 9675 case REFINER_HYBRID_HEX_2D: 9676 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 9677 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9678 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 9679 break; 9680 default: 9681 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9682 } 9683 cMax = cMax < 0 ? cEnd : cMax; 9684 fMax = fMax < 0 ? fEnd : fMax; 9685 eMax = eMax < 0 ? eEnd : eMax; 9686 for (l = 0; l < numLabels; ++l) { 9687 DMLabel label, labelNew; 9688 const char *lname; 9689 PetscBool isDepth; 9690 IS valueIS; 9691 const PetscInt *values; 9692 PetscInt defVal; 9693 PetscInt numValues, val; 9694 9695 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 9696 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 9697 if (isDepth) continue; 9698 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 9699 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 9700 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 9701 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 9702 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 9703 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 9704 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 9705 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 9706 for (val = 0; val < numValues; ++val) { 9707 IS pointIS; 9708 const PetscInt *points; 9709 PetscInt numPoints, n; 9710 9711 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 9712 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 9713 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 9714 /* Ensure refined label is created with same number of strata as 9715 * original (even if no entries here). */ 9716 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 9717 for (n = 0; n < numPoints; ++n) { 9718 const PetscInt p = points[n]; 9719 switch (refiner) { 9720 case REFINER_SIMPLEX_1D: 9721 if ((p >= vStart) && (p < vEnd)) { 9722 /* Old vertices stay the same */ 9723 newp = vStartNew + (p - vStart); 9724 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9725 } else if ((p >= cStart) && (p < cEnd)) { 9726 /* Old cells add new cells and vertex */ 9727 newp = vStartNew + (vEnd - vStart) + (p - cStart); 9728 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9729 for (r = 0; r < 2; ++r) { 9730 newp = cStartNew + (p - cStart)*2 + r; 9731 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9732 } 9733 } 9734 break; 9735 case REFINER_SIMPLEX_2D: 9736 if ((p >= vStart) && (p < vEnd)) { 9737 /* Old vertices stay the same */ 9738 newp = vStartNew + (p - vStart); 9739 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9740 } else if ((p >= fStart) && (p < fEnd)) { 9741 /* Old faces add new faces and vertex */ 9742 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9743 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9744 for (r = 0; r < 2; ++r) { 9745 newp = fStartNew + (p - fStart)*2 + r; 9746 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9747 } 9748 } else if ((p >= cStart) && (p < cEnd)) { 9749 /* Old cells add new cells and interior faces */ 9750 for (r = 0; r < 4; ++r) { 9751 newp = cStartNew + (p - cStart)*4 + r; 9752 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9753 } 9754 for (r = 0; r < 3; ++r) { 9755 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9756 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9757 } 9758 } 9759 break; 9760 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9761 case REFINER_SIMPLEX_TO_HEX_2D: 9762 if ((p >= vStart) && (p < vEnd)) { 9763 /* Old vertices stay the same */ 9764 newp = vStartNew + (p - vStart); 9765 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9766 } else if ((p >= fStart) && (p < fEnd)) { 9767 /* Old faces add new faces and vertex */ 9768 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9769 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9770 for (r = 0; r < 2; ++r) { 9771 newp = fStartNew + (p - fStart)*2 + r; 9772 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9773 } 9774 } else if ((p >= cStart) && (p < cMax)) { 9775 /* Old cells add new cells, interior faces, and a vertex */ 9776 for (r = 0; r < 3; ++r) { 9777 newp = cStartNew + (p - cStart)*3 + r; 9778 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9779 } 9780 for (r = 0; r < 3; ++r) { 9781 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9782 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9783 } 9784 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9785 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9786 } else if ((p >= cMax) && (p < cEnd)) { 9787 /* Old hybrid cells add new cells, interior faces, and a vertex */ 9788 for (r = 0; r < 4; ++r) { 9789 newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9790 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9791 } 9792 for (r = 0; r < 4; ++r) { 9793 newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9794 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9795 } 9796 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9797 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9798 } 9799 break; 9800 case REFINER_HEX_2D: 9801 if ((p >= vStart) && (p < vEnd)) { 9802 /* Old vertices stay the same */ 9803 newp = vStartNew + (p - vStart); 9804 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9805 } else if ((p >= fStart) && (p < fEnd)) { 9806 /* Old faces add new faces and vertex */ 9807 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9808 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9809 for (r = 0; r < 2; ++r) { 9810 newp = fStartNew + (p - fStart)*2 + r; 9811 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9812 } 9813 } else if ((p >= cStart) && (p < cEnd)) { 9814 /* Old cells add new cells and interior faces and vertex */ 9815 for (r = 0; r < 4; ++r) { 9816 newp = cStartNew + (p - cStart)*4 + r; 9817 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9818 } 9819 for (r = 0; r < 4; ++r) { 9820 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9821 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9822 } 9823 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9824 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9825 } 9826 break; 9827 case REFINER_HYBRID_SIMPLEX_2D: 9828 if ((p >= vStart) && (p < vEnd)) { 9829 /* Old vertices stay the same */ 9830 newp = vStartNew + (p - vStart); 9831 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9832 } else if ((p >= fStart) && (p < fMax)) { 9833 /* Old interior faces add new faces and vertex */ 9834 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9835 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9836 for (r = 0; r < 2; ++r) { 9837 newp = fStartNew + (p - fStart)*2 + r; 9838 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9839 } 9840 } else if ((p >= fMax) && (p < fEnd)) { 9841 /* Old hybrid faces stay the same */ 9842 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9843 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9844 } else if ((p >= cStart) && (p < cMax)) { 9845 /* Old interior cells add new cells and interior faces */ 9846 for (r = 0; r < 4; ++r) { 9847 newp = cStartNew + (p - cStart)*4 + r; 9848 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9849 } 9850 for (r = 0; r < 3; ++r) { 9851 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9852 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9853 } 9854 } else if ((p >= cMax) && (p < cEnd)) { 9855 /* Old hybrid cells add new cells and hybrid face */ 9856 for (r = 0; r < 2; ++r) { 9857 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9858 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9859 } 9860 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9861 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9862 } 9863 break; 9864 case REFINER_HYBRID_HEX_2D: 9865 if ((p >= vStart) && (p < vEnd)) { 9866 /* Old vertices stay the same */ 9867 newp = vStartNew + (p - vStart); 9868 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9869 } else if ((p >= fStart) && (p < fMax)) { 9870 /* Old interior faces add new faces and vertex */ 9871 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9872 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9873 for (r = 0; r < 2; ++r) { 9874 newp = fStartNew + (p - fStart)*2 + r; 9875 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9876 } 9877 } else if ((p >= fMax) && (p < fEnd)) { 9878 /* Old hybrid faces stay the same */ 9879 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9880 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9881 } else if ((p >= cStart) && (p < cMax)) { 9882 /* Old interior cells add new cells, interior faces, and vertex */ 9883 for (r = 0; r < 4; ++r) { 9884 newp = cStartNew + (p - cStart)*4 + r; 9885 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9886 } 9887 for (r = 0; r < 4; ++r) { 9888 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9889 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9890 } 9891 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9892 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9893 } else if ((p >= cMax) && (p < cEnd)) { 9894 /* Old hybrid cells add new cells and hybrid face */ 9895 for (r = 0; r < 2; ++r) { 9896 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9897 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9898 } 9899 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9900 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9901 } 9902 break; 9903 case REFINER_SIMPLEX_3D: 9904 if ((p >= vStart) && (p < vEnd)) { 9905 /* Old vertices stay the same */ 9906 newp = vStartNew + (p - vStart); 9907 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9908 } else if ((p >= eStart) && (p < eEnd)) { 9909 /* Old edges add new edges and vertex */ 9910 for (r = 0; r < 2; ++r) { 9911 newp = eStartNew + (p - eStart)*2 + r; 9912 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9913 } 9914 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9915 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9916 } else if ((p >= fStart) && (p < fEnd)) { 9917 /* Old faces add new faces and edges */ 9918 for (r = 0; r < 4; ++r) { 9919 newp = fStartNew + (p - fStart)*4 + r; 9920 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9921 } 9922 for (r = 0; r < 3; ++r) { 9923 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 9924 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9925 } 9926 } else if ((p >= cStart) && (p < cEnd)) { 9927 /* Old cells add new cells and interior faces and edges */ 9928 for (r = 0; r < 8; ++r) { 9929 newp = cStartNew + (p - cStart)*8 + r; 9930 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9931 } 9932 for (r = 0; r < 8; ++r) { 9933 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 9934 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9935 } 9936 for (r = 0; r < 1; ++r) { 9937 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 9938 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9939 } 9940 } 9941 break; 9942 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9943 case REFINER_SIMPLEX_TO_HEX_3D: 9944 if ((p >= vStart) && (p < vEnd)) { 9945 /* Old vertices stay the same */ 9946 newp = vStartNew + (p - vStart); 9947 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9948 } else if ((p >= eStart) && (p < eMax)) { 9949 /* Interior edges add new edges and vertex */ 9950 for (r = 0; r < 2; ++r) { 9951 newp = eStartNew + (p - eStart)*2 + r; 9952 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9953 } 9954 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9955 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9956 } else if ((p >= eMax) && (p < eEnd)) { 9957 /* Hybrid edges stay the same */ 9958 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax; 9959 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9960 } else if ((p >= fStart) && (p < fMax)) { 9961 /* Old faces add new faces, edges and a vertex */ 9962 for (r = 0; r < 3; ++r) { 9963 newp = fStartNew + (p - fStart)*3 + r; 9964 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9965 } 9966 for (r = 0; r < 3; ++r) { 9967 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9968 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9969 } 9970 } else if ((p >= fMax) && (p < fEnd)) { 9971 /* Old hybrid faces add new faces and an edge */ 9972 for (r = 0; r < 2; ++r) { 9973 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9974 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9975 } 9976 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9977 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9978 } else if ((p >= cStart) && (p < cMax)) { 9979 /* Old cells add new cells and interior faces and edges and a vertex */ 9980 for (r = 0; r < 4; ++r) { 9981 newp = cStartNew + (p - cStart)*4 + r; 9982 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9983 } 9984 for (r = 0; r < 6; ++r) { 9985 newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9986 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9987 } 9988 for (r = 0; r < 4; ++r) { 9989 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9990 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9991 } 9992 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart; 9993 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9994 } else if ((p >= cMax) && (p < cEnd)) { 9995 /* Old hybrid cells add new cells and interior faces and an edge */ 9996 for (r = 0; r < 3; ++r) { 9997 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9998 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9999 } 10000 for (r = 0; r < 3; ++r) { 10001 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 10002 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10003 } 10004 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax; 10005 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10006 } 10007 break; 10008 case REFINER_HYBRID_SIMPLEX_3D: 10009 if ((p >= vStart) && (p < vEnd)) { 10010 /* Interior vertices stay the same */ 10011 newp = vStartNew + (p - vStart); 10012 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10013 } else if ((p >= eStart) && (p < eMax)) { 10014 /* Interior edges add new edges and vertex */ 10015 for (r = 0; r < 2; ++r) { 10016 newp = eStartNew + (p - eStart)*2 + r; 10017 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10018 } 10019 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10020 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10021 } else if ((p >= eMax) && (p < eEnd)) { 10022 /* Hybrid edges stay the same */ 10023 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 10024 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10025 } else if ((p >= fStart) && (p < fMax)) { 10026 /* Interior faces add new faces and edges */ 10027 for (r = 0; r < 4; ++r) { 10028 newp = fStartNew + (p - fStart)*4 + r; 10029 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10030 } 10031 for (r = 0; r < 3; ++r) { 10032 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 10033 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10034 } 10035 } else if ((p >= fMax) && (p < fEnd)) { 10036 /* Hybrid faces add new faces and edges */ 10037 for (r = 0; r < 2; ++r) { 10038 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 10039 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10040 } 10041 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 10042 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10043 } else if ((p >= cStart) && (p < cMax)) { 10044 /* Interior cells add new cells, faces, and edges */ 10045 for (r = 0; r < 8; ++r) { 10046 newp = cStartNew + (p - cStart)*8 + r; 10047 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10048 } 10049 for (r = 0; r < 8; ++r) { 10050 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 10051 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10052 } 10053 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 10054 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10055 } else if ((p >= cMax) && (p < cEnd)) { 10056 /* Hybrid cells add new cells and faces */ 10057 for (r = 0; r < 4; ++r) { 10058 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10059 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10060 } 10061 for (r = 0; r < 3; ++r) { 10062 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 10063 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10064 } 10065 } 10066 break; 10067 case REFINER_HEX_3D: 10068 if ((p >= vStart) && (p < vEnd)) { 10069 /* Old vertices stay the same */ 10070 newp = vStartNew + (p - vStart); 10071 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10072 } else if ((p >= eStart) && (p < eEnd)) { 10073 /* Old edges add new edges and vertex */ 10074 for (r = 0; r < 2; ++r) { 10075 newp = eStartNew + (p - eStart)*2 + r; 10076 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10077 } 10078 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10079 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10080 } else if ((p >= fStart) && (p < fEnd)) { 10081 /* Old faces add new faces, edges, and vertex */ 10082 for (r = 0; r < 4; ++r) { 10083 newp = fStartNew + (p - fStart)*4 + r; 10084 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10085 } 10086 for (r = 0; r < 4; ++r) { 10087 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 10088 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10089 } 10090 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 10091 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10092 } else if ((p >= cStart) && (p < cEnd)) { 10093 /* Old cells add new cells, faces, edges, and vertex */ 10094 for (r = 0; r < 8; ++r) { 10095 newp = cStartNew + (p - cStart)*8 + r; 10096 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10097 } 10098 for (r = 0; r < 12; ++r) { 10099 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 10100 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10101 } 10102 for (r = 0; r < 6; ++r) { 10103 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 10104 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10105 } 10106 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 10107 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10108 } 10109 break; 10110 case REFINER_HYBRID_HEX_3D: 10111 if ((p >= vStart) && (p < vEnd)) { 10112 /* Interior vertices stay the same */ 10113 newp = vStartNew + (p - vStart); 10114 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10115 } else if ((p >= eStart) && (p < eMax)) { 10116 /* Interior edges add new edges and vertex */ 10117 for (r = 0; r < 2; ++r) { 10118 newp = eStartNew + (p - eStart)*2 + r; 10119 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10120 } 10121 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10122 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10123 } else if ((p >= eMax) && (p < eEnd)) { 10124 /* Hybrid edges stay the same */ 10125 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 10126 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10127 } else if ((p >= fStart) && (p < fMax)) { 10128 /* Interior faces add new faces, edges, and vertex */ 10129 for (r = 0; r < 4; ++r) { 10130 newp = fStartNew + (p - fStart)*4 + r; 10131 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10132 } 10133 for (r = 0; r < 4; ++r) { 10134 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 10135 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10136 } 10137 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 10138 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10139 } else if ((p >= fMax) && (p < fEnd)) { 10140 /* Hybrid faces add new faces and edges */ 10141 for (r = 0; r < 2; ++r) { 10142 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 10143 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10144 } 10145 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 10146 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10147 } else if ((p >= cStart) && (p < cMax)) { 10148 /* Interior cells add new cells, faces, edges, and vertex */ 10149 for (r = 0; r < 8; ++r) { 10150 newp = cStartNew + (p - cStart)*8 + r; 10151 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10152 } 10153 for (r = 0; r < 12; ++r) { 10154 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 10155 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10156 } 10157 for (r = 0; r < 6; ++r) { 10158 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 10159 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10160 } 10161 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 10162 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10163 } else if ((p >= cMax) && (p < cEnd)) { 10164 /* Hybrid cells add new cells, faces, and edges */ 10165 for (r = 0; r < 4; ++r) { 10166 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10167 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10168 } 10169 for (r = 0; r < 4; ++r) { 10170 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 10171 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10172 } 10173 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 10174 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10175 } 10176 break; 10177 default: 10178 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 10179 } 10180 } 10181 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 10182 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 10183 } 10184 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 10185 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 10186 } 10187 PetscFunctionReturn(0); 10188 } 10189 10190 /* This will only work for interpolated meshes */ 10191 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 10192 { 10193 DM rdm; 10194 PetscInt *depthSize; 10195 PetscInt dim, embedDim, depth = 0, d, pStart = 0, pEnd = 0; 10196 PetscErrorCode ierr; 10197 10198 PetscFunctionBegin; 10199 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 10200 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 10201 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10202 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 10203 ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr); 10204 ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr); 10205 /* Calculate number of new points of each depth */ 10206 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10207 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 10208 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10209 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 10210 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10211 /* Step 1: Set chart */ 10212 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 10213 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 10214 /* Step 2: Set cone/support sizes (automatically stratifies) */ 10215 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10216 /* Step 3: Setup refined DM */ 10217 ierr = DMSetUp(rdm);CHKERRQ(ierr); 10218 /* Step 4: Set cones and supports (automatically symmetrizes) */ 10219 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10220 /* Step 5: Create pointSF */ 10221 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10222 /* Step 6: Create labels */ 10223 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10224 /* Step 7: Set coordinates */ 10225 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10226 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10227 10228 *dmRefined = rdm; 10229 PetscFunctionReturn(0); 10230 } 10231 10232 /*@ 10233 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 10234 10235 Input Parameter: 10236 . dm - The coarse DM 10237 10238 Output Parameter: 10239 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 10240 10241 Level: developer 10242 10243 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 10244 @*/ 10245 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 10246 { 10247 CellRefiner cellRefiner; 10248 PetscInt *depthSize, *fpoints; 10249 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 10250 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 10251 PetscErrorCode ierr; 10252 10253 PetscFunctionBegin; 10254 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10255 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 10256 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 10257 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10258 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10259 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10260 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 10261 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 10262 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 10263 switch (cellRefiner) { 10264 case REFINER_SIMPLEX_1D: 10265 case REFINER_SIMPLEX_2D: 10266 case REFINER_HYBRID_SIMPLEX_2D: 10267 case REFINER_HEX_2D: 10268 case REFINER_HYBRID_HEX_2D: 10269 case REFINER_SIMPLEX_3D: 10270 case REFINER_HYBRID_SIMPLEX_3D: 10271 case REFINER_HEX_3D: 10272 case REFINER_HYBRID_HEX_3D: 10273 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 10274 break; 10275 default: 10276 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[cellRefiner]); 10277 } 10278 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 10279 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10280 PetscFunctionReturn(0); 10281 } 10282 10283 /*@ 10284 DMPlexSetRefinementUniform - Set the flag for uniform refinement 10285 10286 Input Parameters: 10287 + dm - The DM 10288 - refinementUniform - The flag for uniform refinement 10289 10290 Level: developer 10291 10292 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10293 @*/ 10294 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 10295 { 10296 DM_Plex *mesh = (DM_Plex*) dm->data; 10297 10298 PetscFunctionBegin; 10299 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10300 mesh->refinementUniform = refinementUniform; 10301 PetscFunctionReturn(0); 10302 } 10303 10304 /*@ 10305 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 10306 10307 Input Parameter: 10308 . dm - The DM 10309 10310 Output Parameter: 10311 . refinementUniform - The flag for uniform refinement 10312 10313 Level: developer 10314 10315 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10316 @*/ 10317 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 10318 { 10319 DM_Plex *mesh = (DM_Plex*) dm->data; 10320 10321 PetscFunctionBegin; 10322 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10323 PetscValidPointer(refinementUniform, 2); 10324 *refinementUniform = mesh->refinementUniform; 10325 PetscFunctionReturn(0); 10326 } 10327 10328 /*@ 10329 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 10330 10331 Input Parameters: 10332 + dm - The DM 10333 - refinementLimit - The maximum cell volume in the refined mesh 10334 10335 Level: developer 10336 10337 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10338 @*/ 10339 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 10340 { 10341 DM_Plex *mesh = (DM_Plex*) dm->data; 10342 10343 PetscFunctionBegin; 10344 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10345 mesh->refinementLimit = refinementLimit; 10346 PetscFunctionReturn(0); 10347 } 10348 10349 /*@ 10350 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 10351 10352 Input Parameter: 10353 . dm - The DM 10354 10355 Output Parameter: 10356 . refinementLimit - The maximum cell volume in the refined mesh 10357 10358 Level: developer 10359 10360 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10361 @*/ 10362 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 10363 { 10364 DM_Plex *mesh = (DM_Plex*) dm->data; 10365 10366 PetscFunctionBegin; 10367 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10368 PetscValidPointer(refinementLimit, 2); 10369 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 10370 *refinementLimit = mesh->refinementLimit; 10371 PetscFunctionReturn(0); 10372 } 10373 10374 /*@ 10375 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 10376 10377 Input Parameters: 10378 + dm - The DM 10379 - refinementFunc - Function giving the maximum cell volume in the refined mesh 10380 10381 Note: The calling sequence is refinementFunc(coords, limit) 10382 $ coords - Coordinates of the current point, usually a cell centroid 10383 $ limit - The maximum cell volume for a cell containing this point 10384 10385 Level: developer 10386 10387 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10388 @*/ 10389 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 10390 { 10391 DM_Plex *mesh = (DM_Plex*) dm->data; 10392 10393 PetscFunctionBegin; 10394 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10395 mesh->refinementFunc = refinementFunc; 10396 PetscFunctionReturn(0); 10397 } 10398 10399 /*@ 10400 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 10401 10402 Input Parameter: 10403 . dm - The DM 10404 10405 Output Parameter: 10406 . refinementFunc - Function giving the maximum cell volume in the refined mesh 10407 10408 Note: The calling sequence is refinementFunc(coords, limit) 10409 $ coords - Coordinates of the current point, usually a cell centroid 10410 $ limit - The maximum cell volume for a cell containing this point 10411 10412 Level: developer 10413 10414 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10415 @*/ 10416 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 10417 { 10418 DM_Plex *mesh = (DM_Plex*) dm->data; 10419 10420 PetscFunctionBegin; 10421 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10422 PetscValidPointer(refinementFunc, 2); 10423 *refinementFunc = mesh->refinementFunc; 10424 PetscFunctionReturn(0); 10425 } 10426 10427 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 10428 { 10429 PetscInt dim, cStart, cEnd, coneSize, cMax, fMax; 10430 PetscErrorCode ierr; 10431 10432 PetscFunctionBegin; 10433 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10434 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 10435 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 10436 ierr = DMPlexGetConeSize(dm, cStart, &coneSize);CHKERRQ(ierr); 10437 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 10438 switch (dim) { 10439 case 1: 10440 switch (coneSize) { 10441 case 2: 10442 *cellRefiner = REFINER_SIMPLEX_1D; 10443 break; 10444 default: 10445 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10446 } 10447 break; 10448 case 2: 10449 switch (coneSize) { 10450 case 3: 10451 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; 10452 else *cellRefiner = REFINER_SIMPLEX_2D; 10453 break; 10454 case 4: 10455 if (cMax >= 0 && fMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_2D; 10456 else *cellRefiner = REFINER_HEX_2D; 10457 break; 10458 default: 10459 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10460 } 10461 break; 10462 case 3: 10463 switch (coneSize) { 10464 case 4: 10465 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 10466 else *cellRefiner = REFINER_SIMPLEX_3D; 10467 break; 10468 case 5: 10469 if (cMax == 0) *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; 10470 else SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10471 break; 10472 case 6: 10473 if (cMax >= 0) *cellRefiner = REFINER_HYBRID_HEX_3D; 10474 else *cellRefiner = REFINER_HEX_3D; 10475 break; 10476 default: 10477 SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown coneSize %D in dimension %D for cell refiner", coneSize, dim); 10478 } 10479 break; 10480 default: 10481 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown dimension %D for cell refiner", dim); 10482 } 10483 PetscFunctionReturn(0); 10484 } 10485 10486 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 10487 { 10488 PetscBool isUniform; 10489 PetscErrorCode ierr; 10490 10491 PetscFunctionBegin; 10492 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10493 if (isUniform) { 10494 CellRefiner cellRefiner; 10495 PetscBool localized; 10496 10497 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10498 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10499 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 10500 ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 10501 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 10502 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 10503 } else { 10504 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 10505 } 10506 PetscFunctionReturn(0); 10507 } 10508 10509 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 10510 { 10511 DM cdm = dm; 10512 PetscInt r; 10513 PetscBool isUniform, localized; 10514 PetscErrorCode ierr; 10515 10516 PetscFunctionBegin; 10517 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10518 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10519 if (isUniform) { 10520 for (r = 0; r < nlevels; ++r) { 10521 CellRefiner cellRefiner; 10522 10523 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 10524 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 10525 ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 10526 ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 10527 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10528 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10529 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10530 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 10531 cdm = dmRefined[r]; 10532 } 10533 } else { 10534 for (r = 0; r < nlevels; ++r) { 10535 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 10536 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10537 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10538 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10539 cdm = dmRefined[r]; 10540 } 10541 } 10542 PetscFunctionReturn(0); 10543 } 10544