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 break; 251 dim = 3; 252 if (numSubcells) *numSubcells = 8; 253 if (v0) { 254 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 255 /* A */ 256 v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0; 257 j[0+0] = 0.5; j[0+1] = 0.0; j[0+2] = 0.0; 258 j[0+3] = 0.0; j[0+4] = 0.5; j[0+5] = 0.0; 259 j[0+6] = 0.0; j[0+7] = 0.0; j[0+8] = 0.5; 260 /* B */ 261 v[3+0] = -1.0; v[3+1] = 0.0; v[3+2] = -1.0; 262 j[9+0] = 0.5; j[9+1] = 0.0; j[9+2] = 0.0; 263 j[9+3] = 0.0; j[9+4] = 0.5; j[9+5] = 0.0; 264 j[9+6] = 0.0; j[9+7] = 0.0; j[9+8] = 0.5; 265 /* C */ 266 v[6+0] = 0.0; v[6+1] = 0.0; v[6+2] = -1.0; 267 j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0; 268 j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0; 269 j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5; 270 /* D */ 271 v[9+0] = 0.0; v[9+1] = -1.0; v[9+2] = -1.0; 272 j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0; 273 j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0; 274 j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5; 275 /* E */ 276 v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] = 0.0; 277 j[36+0] = 0.5; j[36+1] = 0.0; j[36+2] = 0.0; 278 j[36+3] = 0.0; j[36+4] = 0.5; j[36+5] = 0.0; 279 j[36+6] = 0.0; j[36+7] = 0.0; j[36+8] = 0.5; 280 /* F */ 281 v[15+0] = 0.0; v[15+1] = -1.0; v[15+2] = 0.0; 282 j[45+0] = 0.5; j[45+1] = 0.0; j[45+2] = 0.0; 283 j[45+3] = 0.0; j[45+4] = 0.5; j[45+5] = 0.0; 284 j[45+6] = 0.0; j[45+7] = 0.0; j[45+8] = 0.5; 285 /* G */ 286 v[18+0] = 0.0; v[18+1] = 0.0; v[18+2] = 0.0; 287 j[54+0] = 0.5; j[54+1] = 0.0; j[54+2] = 0.0; 288 j[54+3] = 0.0; j[54+4] = 0.5; j[54+5] = 0.0; 289 j[54+6] = 0.0; j[54+7] = 0.0; j[54+8] = 0.5; 290 /* H */ 291 v[21+0] = -1.0; v[21+1] = 0.0; v[21+2] = 0.0; 292 j[63+0] = 0.5; j[63+1] = 0.0; j[63+2] = 0.0; 293 j[63+3] = 0.0; j[63+4] = 0.5; j[63+5] = 0.0; 294 j[63+6] = 0.0; j[63+7] = 0.0; j[63+8] = 0.5; 295 for (s = 0; s < 8; ++s) { 296 DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]); 297 DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 298 } 299 } 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 default: 337 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 338 } 339 PetscFunctionReturn(0); 340 } 341 342 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 343 { 344 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 345 PetscErrorCode ierr; 346 347 PetscFunctionBegin; 348 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 349 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 350 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 351 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 352 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 353 switch (refiner) { 354 case REFINER_NOOP: 355 break; 356 case REFINER_SIMPLEX_1D: 357 depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */ 358 depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */ 359 break; 360 case REFINER_SIMPLEX_2D: 361 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 362 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 363 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 364 break; 365 case REFINER_HYBRID_SIMPLEX_2D: 366 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 367 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 368 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 369 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 */ 370 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, hybrid cells split into 2 cells */ 371 break; 372 case REFINER_SIMPLEX_TO_HEX_2D: 373 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 374 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 375 depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */ 376 break; 377 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 378 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 379 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 380 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 */ 381 depthSize[2] = 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every cell split into 3 cells, hybrid cells split in 4 */ 382 break; 383 case REFINER_HEX_2D: 384 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 385 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 386 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 387 break; 388 case REFINER_HYBRID_HEX_2D: 389 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 390 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 391 /* Quadrilateral */ 392 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 393 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 394 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 395 /* Segment Prisms */ 396 depthSize[0] += 0; /* No hybrid vertices */ 397 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 398 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 399 break; 400 case REFINER_SIMPLEX_3D: 401 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 402 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 */ 403 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 404 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 405 break; 406 case REFINER_HYBRID_SIMPLEX_3D: 407 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 408 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 409 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 410 /* Tetrahedra */ 411 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 412 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 */ 413 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 414 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 415 /* Triangular Prisms */ 416 depthSize[0] += 0; /* No hybrid vertices */ 417 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 418 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 419 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 420 break; 421 case REFINER_SIMPLEX_TO_HEX_3D: 422 depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */ 423 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 */ 424 depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */ 425 depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 426 break; 427 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 428 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 429 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 430 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 431 /* Tetrahedra */ 432 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every interior edge, face and cell */ 433 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 */ 434 depthSize[2] = 3*(fMax - fStart) + 6*(cMax - cStart); /* Every interior face split into 3 faces, 6 faces added for each interior cell */ 435 depthSize[3] = 4*(cMax - cStart); /* Every interior cell split into 8 cells */ 436 /* Triangular Prisms */ 437 depthSize[0] += 0; /* No hybrid vertices */ 438 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and cell */ 439 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 440 depthSize[3] += 3*(cEnd - cMax); /* Every hybrid cell split into 3 cells */ 441 break; 442 case REFINER_HEX_3D: 443 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 444 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 */ 445 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 446 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 447 break; 448 case REFINER_HYBRID_HEX_3D: 449 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 450 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 451 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 452 /* Hexahedra */ 453 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 454 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 */ 455 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 456 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 457 /* Quadrilateral Prisms */ 458 depthSize[0] += 0; /* No hybrid vertices */ 459 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 460 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 461 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 462 break; 463 default: 464 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 465 } 466 PetscFunctionReturn(0); 467 } 468 469 /* Return triangle edge for orientation o, if it is r for o == 0 */ 470 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 471 return (o < 0 ? 2-(o+r) : o+r)%3; 472 } 473 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 474 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 475 } 476 477 /* Return triangle subface for orientation o, if it is r for o == 0 */ 478 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 479 return (o < 0 ? 3-(o+r) : o+r)%3; 480 } 481 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 482 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 483 } 484 485 /* Return the interior edge number connecting the midpoints of the triangle edges r 486 and r+1 in the transitive closure for triangle orientation o */ 487 PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) { 488 return (o < 0 ? 1-(o+r) : o+r)%3; 489 } 490 PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) { 491 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 492 } 493 494 /* Return the interior edge number connecting the midpoint of the triangle edge r 495 (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */ 496 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) { 497 return (o < 0 ? 2-(o+r) : o+r)%3; 498 } 499 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) { 500 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 501 } 502 503 /* Return quad edge for orientation o, if it is r for o == 0 */ 504 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 505 return (o < 0 ? 3-(o+r) : o+r)%4; 506 } 507 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 508 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 509 } 510 511 /* Return quad subface for orientation o, if it is r for o == 0 */ 512 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 513 return (o < 0 ? 4-(o+r) : o+r)%4; 514 } 515 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 516 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 517 } 518 519 static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd) 520 { 521 IS cIS; 522 PetscErrorCode ierr; 523 524 PetscFunctionBegin; 525 ierr = ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);CHKERRQ(ierr); 526 ierr = DMLabelSetStratumIS(label, value, cIS);CHKERRQ(ierr); 527 ierr = ISDestroy(&cIS);CHKERRQ(ierr); 528 PetscFunctionReturn(0); 529 } 530 531 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 532 { 533 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; 534 DMLabel depthLabel; 535 PetscErrorCode ierr; 536 537 PetscFunctionBegin; 538 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 539 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 540 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 541 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 542 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 543 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 544 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 545 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 546 ierr = DMCreateLabel(rdm,"depth");CHKERRQ(ierr); 547 ierr = DMPlexGetDepthLabel(rdm,&depthLabel);CHKERRQ(ierr); 548 ierr = DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);CHKERRQ(ierr); 549 if (depth > 2) ierr = DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);CHKERRQ(ierr); 550 if (depth > 1) ierr = DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);CHKERRQ(ierr); 551 if (depth > 0) ierr = DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);CHKERRQ(ierr); 552 { 553 DM_Plex *plex = (DM_Plex *) rdm->data; 554 ierr = PetscObjectStateGet((PetscObject) depthLabel, &plex->depthState);CHKERRQ(ierr); 555 } 556 if (!refiner) PetscFunctionReturn(0); 557 switch (refiner) { 558 case REFINER_SIMPLEX_1D: 559 /* All cells have 2 vertices */ 560 for (c = cStart; c < cEnd; ++c) { 561 for (r = 0; r < 2; ++r) { 562 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 563 564 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 565 } 566 } 567 /* Old vertices have identical supports */ 568 for (v = vStart; v < vEnd; ++v) { 569 const PetscInt newp = vStartNew + (v - vStart); 570 PetscInt size; 571 572 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 573 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 574 } 575 /* Cell vertices have support 2 */ 576 for (c = cStart; c < cEnd; ++c) { 577 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 578 579 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 580 } 581 break; 582 case REFINER_SIMPLEX_2D: 583 /* All cells have 3 faces */ 584 for (c = cStart; c < cEnd; ++c) { 585 for (r = 0; r < 4; ++r) { 586 const PetscInt newp = (c - cStart)*4 + r; 587 588 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 589 } 590 } 591 /* Split faces have 2 vertices and the same cells as the parent */ 592 for (f = fStart; f < fEnd; ++f) { 593 for (r = 0; r < 2; ++r) { 594 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 595 PetscInt size; 596 597 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 598 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 599 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 600 } 601 } 602 /* Interior faces have 2 vertices and 2 cells */ 603 for (c = cStart; c < cEnd; ++c) { 604 for (r = 0; r < 3; ++r) { 605 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 606 607 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 608 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 609 } 610 } 611 /* Old vertices have identical supports */ 612 for (v = vStart; v < vEnd; ++v) { 613 const PetscInt newp = vStartNew + (v - vStart); 614 PetscInt size; 615 616 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 617 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 618 } 619 /* Face vertices have 2 + cells*2 supports */ 620 for (f = fStart; f < fEnd; ++f) { 621 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 622 PetscInt size; 623 624 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 625 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 626 } 627 break; 628 case REFINER_SIMPLEX_TO_HEX_2D: 629 /* All cells have 4 faces */ 630 for (c = cStart; c < cEnd; ++c) { 631 for (r = 0; r < 3; ++r) { 632 const PetscInt newp = (c - cStart)*3 + r; 633 634 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 635 } 636 } 637 /* Split faces have 2 vertices and the same cells as the parent */ 638 for (f = fStart; f < fEnd; ++f) { 639 for (r = 0; r < 2; ++r) { 640 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 641 PetscInt size; 642 643 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 644 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 645 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 646 } 647 } 648 /* Interior faces have 2 vertices and 2 cells */ 649 for (c = cStart; c < cEnd; ++c) { 650 for (r = 0; r < 3; ++r) { 651 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 652 653 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 654 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 655 } 656 } 657 /* Old vertices have identical supports */ 658 for (v = vStart; v < vEnd; ++v) { 659 const PetscInt newp = vStartNew + (v - vStart); 660 PetscInt size; 661 662 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 663 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 664 } 665 /* Split-face vertices have cells + 2 supports */ 666 for (f = fStart; f < fEnd; ++f) { 667 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 668 PetscInt size; 669 670 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 671 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 672 } 673 /* Interior vertices have 3 supports */ 674 for (c = cStart; c < cEnd; ++c) { 675 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 676 677 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 678 } 679 break; 680 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 681 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 682 /* the mesh is no longer hybrid */ 683 cMax = PetscMin(cEnd, cMax); 684 /* All cells have 4 faces */ 685 for (c = cStart; c < cMax; ++c) { 686 for (r = 0; r < 3; ++r) { 687 const PetscInt newp = (c - cStart)*3 + r; 688 689 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 690 } 691 } 692 for (c = cMax; c < cEnd; ++c) { 693 for (r = 0; r < 4; ++r) { 694 const PetscInt newp = (cMax - cStart)*3 + (c - cMax)*4 + r; 695 696 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 697 } 698 } 699 /* Split faces have 2 vertices and the same cells as the parent */ 700 for (f = fStart; f < fEnd; ++f) { 701 for (r = 0; r < 2; ++r) { 702 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 703 PetscInt size; 704 705 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 706 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 707 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 708 } 709 } 710 /* Interior faces have 2 vertices and 2 cells */ 711 for (c = cStart; c < cMax; ++c) { 712 for (r = 0; r < 3; ++r) { 713 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 714 715 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 716 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 717 } 718 } 719 /* Hybrid interior faces have 2 vertices and 2 cells */ 720 for (c = cMax; c < cEnd; ++c) { 721 for (r = 0; r < 4; ++r) { 722 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 723 724 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 725 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 726 } 727 } 728 /* Old vertices have identical supports */ 729 for (v = vStart; v < vEnd; ++v) { 730 const PetscInt newp = vStartNew + (v - vStart); 731 PetscInt size; 732 733 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 734 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 735 } 736 /* Split-face vertices have cells + 2 supports */ 737 for (f = fStart; f < fEnd; ++f) { 738 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 739 PetscInt size; 740 741 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 742 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 743 } 744 /* Interior vertices have 3 supports */ 745 for (c = cStart; c < cMax; ++c) { 746 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 747 748 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 749 } 750 /* Hybrid interior vertices have 4 supports */ 751 for (c = cMax; c < cEnd; ++c) { 752 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 753 754 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 755 } 756 break; 757 case REFINER_HEX_2D: 758 /* All cells have 4 faces */ 759 for (c = cStart; c < cEnd; ++c) { 760 for (r = 0; r < 4; ++r) { 761 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 762 763 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 764 } 765 } 766 /* Split faces have 2 vertices and the same cells as the parent */ 767 for (f = fStart; f < fEnd; ++f) { 768 for (r = 0; r < 2; ++r) { 769 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 770 PetscInt size; 771 772 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 773 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 774 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 775 } 776 } 777 /* Interior faces have 2 vertices and 2 cells */ 778 for (c = cStart; c < cEnd; ++c) { 779 for (r = 0; r < 4; ++r) { 780 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 781 782 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 783 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 784 } 785 } 786 /* Old vertices have identical supports */ 787 for (v = vStart; v < vEnd; ++v) { 788 const PetscInt newp = vStartNew + (v - vStart); 789 PetscInt size; 790 791 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 792 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 793 } 794 /* Face vertices have 2 + cells supports */ 795 for (f = fStart; f < fEnd; ++f) { 796 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 797 PetscInt size; 798 799 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 800 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 801 } 802 /* Cell vertices have 4 supports */ 803 for (c = cStart; c < cEnd; ++c) { 804 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 805 806 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 807 } 808 break; 809 case REFINER_HYBRID_SIMPLEX_2D: 810 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 811 cMax = PetscMin(cEnd, cMax); 812 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 813 fMax = PetscMin(fEnd, fMax); 814 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 815 /* Interior cells have 3 faces */ 816 for (c = cStart; c < cMax; ++c) { 817 for (r = 0; r < 4; ++r) { 818 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 819 820 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 821 } 822 } 823 /* Hybrid cells have 4 faces */ 824 for (c = cMax; c < cEnd; ++c) { 825 for (r = 0; r < 2; ++r) { 826 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 827 828 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 829 } 830 } 831 /* Interior split faces have 2 vertices and the same cells as the parent */ 832 for (f = fStart; f < fMax; ++f) { 833 for (r = 0; r < 2; ++r) { 834 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 835 PetscInt size; 836 837 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 838 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 839 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 840 } 841 } 842 /* Interior cell faces have 2 vertices and 2 cells */ 843 for (c = cStart; c < cMax; ++c) { 844 for (r = 0; r < 3; ++r) { 845 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 846 847 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 848 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 849 } 850 } 851 /* Hybrid faces have 2 vertices and the same cells */ 852 for (f = fMax; f < fEnd; ++f) { 853 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 854 PetscInt size; 855 856 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 857 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 858 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 859 } 860 /* Hybrid cell faces have 2 vertices and 2 cells */ 861 for (c = cMax; c < cEnd; ++c) { 862 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 863 864 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 865 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 866 } 867 /* Old vertices have identical supports */ 868 for (v = vStart; v < vEnd; ++v) { 869 const PetscInt newp = vStartNew + (v - vStart); 870 PetscInt size; 871 872 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 873 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 874 } 875 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 876 for (f = fStart; f < fMax; ++f) { 877 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 878 const PetscInt *support; 879 PetscInt size, newSize = 2, s; 880 881 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 882 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 883 for (s = 0; s < size; ++s) { 884 if (support[s] >= cMax) newSize += 1; 885 else newSize += 2; 886 } 887 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 888 } 889 break; 890 case REFINER_HYBRID_HEX_2D: 891 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 892 cMax = PetscMin(cEnd, cMax); 893 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 894 fMax = PetscMin(fEnd, fMax); 895 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 896 /* Interior cells have 4 faces */ 897 for (c = cStart; c < cMax; ++c) { 898 for (r = 0; r < 4; ++r) { 899 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 900 901 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 902 } 903 } 904 /* Hybrid cells have 4 faces */ 905 for (c = cMax; c < cEnd; ++c) { 906 for (r = 0; r < 2; ++r) { 907 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 908 909 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 910 } 911 } 912 /* Interior split faces have 2 vertices and the same cells as the parent */ 913 for (f = fStart; f < fMax; ++f) { 914 for (r = 0; r < 2; ++r) { 915 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 916 PetscInt size; 917 918 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 919 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 920 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 921 } 922 } 923 /* Interior cell faces have 2 vertices and 2 cells */ 924 for (c = cStart; c < cMax; ++c) { 925 for (r = 0; r < 4; ++r) { 926 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 927 928 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 929 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 930 } 931 } 932 /* Hybrid faces have 2 vertices and the same cells */ 933 for (f = fMax; f < fEnd; ++f) { 934 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 935 PetscInt size; 936 937 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 938 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 939 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 940 } 941 /* Hybrid cell faces have 2 vertices and 2 cells */ 942 for (c = cMax; c < cEnd; ++c) { 943 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 944 945 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 946 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 947 } 948 /* Old vertices have identical supports */ 949 for (v = vStart; v < vEnd; ++v) { 950 const PetscInt newp = vStartNew + (v - vStart); 951 PetscInt size; 952 953 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 954 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 955 } 956 /* Face vertices have 2 + cells supports */ 957 for (f = fStart; f < fMax; ++f) { 958 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 959 PetscInt size; 960 961 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 962 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 963 } 964 /* Cell vertices have 4 supports */ 965 for (c = cStart; c < cMax; ++c) { 966 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 967 968 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 969 } 970 break; 971 case REFINER_SIMPLEX_3D: 972 /* All cells have 4 faces */ 973 for (c = cStart; c < cEnd; ++c) { 974 for (r = 0; r < 8; ++r) { 975 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 976 977 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 978 } 979 } 980 /* Split faces have 3 edges and the same cells as the parent */ 981 for (f = fStart; f < fEnd; ++f) { 982 for (r = 0; r < 4; ++r) { 983 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 984 PetscInt size; 985 986 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 987 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 988 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 989 } 990 } 991 /* Interior cell faces have 3 edges and 2 cells */ 992 for (c = cStart; c < cEnd; ++c) { 993 for (r = 0; r < 8; ++r) { 994 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 995 996 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 997 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 998 } 999 } 1000 /* Split edges have 2 vertices and the same faces */ 1001 for (e = eStart; e < eEnd; ++e) { 1002 for (r = 0; r < 2; ++r) { 1003 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1004 PetscInt size; 1005 1006 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1007 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1008 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1009 } 1010 } 1011 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 1012 for (f = fStart; f < fEnd; ++f) { 1013 for (r = 0; r < 3; ++r) { 1014 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1015 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 1016 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 1017 1018 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1019 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1020 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1021 for (s = 0; s < supportSize; ++s) { 1022 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1023 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1024 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1025 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1026 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 1027 er = GetTriMidEdgeInverse_Static(ornt[c], r); 1028 if (er == eint[c]) { 1029 intFaces += 1; 1030 } else { 1031 intFaces += 2; 1032 } 1033 } 1034 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 1035 } 1036 } 1037 /* Interior cell edges have 2 vertices and 4 faces */ 1038 for (c = cStart; c < cEnd; ++c) { 1039 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1040 1041 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1042 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1043 } 1044 /* Old vertices have identical supports */ 1045 for (v = vStart; v < vEnd; ++v) { 1046 const PetscInt newp = vStartNew + (v - vStart); 1047 PetscInt size; 1048 1049 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1050 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1051 } 1052 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 1053 for (e = eStart; e < eEnd; ++e) { 1054 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1055 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 1056 1057 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1058 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1059 for (s = 0; s < starSize*2; s += 2) { 1060 const PetscInt *cone, *ornt; 1061 PetscInt e01, e23; 1062 1063 if ((star[s] >= cStart) && (star[s] < cEnd)) { 1064 /* Check edge 0-1 */ 1065 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1066 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1067 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1068 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1069 /* Check edge 2-3 */ 1070 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1071 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1072 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1073 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1074 if ((e01 == e) || (e23 == e)) ++cellSize; 1075 } 1076 } 1077 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1078 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 1079 } 1080 break; 1081 case REFINER_HYBRID_SIMPLEX_3D: 1082 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 1083 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1084 /* Interior cells have 4 faces */ 1085 for (c = cStart; c < cMax; ++c) { 1086 for (r = 0; r < 8; ++r) { 1087 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1088 1089 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1090 } 1091 } 1092 /* Hybrid cells have 5 faces */ 1093 for (c = cMax; c < cEnd; ++c) { 1094 for (r = 0; r < 4; ++r) { 1095 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1096 1097 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 1098 } 1099 } 1100 /* Interior split faces have 3 edges and the same cells as the parent */ 1101 for (f = fStart; f < fMax; ++f) { 1102 for (r = 0; r < 4; ++r) { 1103 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1104 PetscInt size; 1105 1106 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 1107 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1108 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1109 } 1110 } 1111 /* Interior cell faces have 3 edges and 2 cells */ 1112 for (c = cStart; c < cMax; ++c) { 1113 for (r = 0; r < 8; ++r) { 1114 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 1115 1116 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 1117 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1118 } 1119 } 1120 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1121 for (f = fMax; f < fEnd; ++f) { 1122 for (r = 0; r < 2; ++r) { 1123 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 1124 PetscInt size; 1125 1126 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1127 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1128 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1129 } 1130 } 1131 /* Hybrid cells faces have 4 edges and 2 cells */ 1132 for (c = cMax; c < cEnd; ++c) { 1133 for (r = 0; r < 3; ++r) { 1134 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1135 1136 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1137 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1138 } 1139 } 1140 /* Interior split edges have 2 vertices and the same faces */ 1141 for (e = eStart; e < eMax; ++e) { 1142 for (r = 0; r < 2; ++r) { 1143 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1144 PetscInt size; 1145 1146 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1147 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1148 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1149 } 1150 } 1151 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 1152 for (f = fStart; f < fMax; ++f) { 1153 for (r = 0; r < 3; ++r) { 1154 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1155 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 1156 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 1157 1158 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1159 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1160 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1161 for (s = 0; s < supportSize; ++s) { 1162 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1163 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1164 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1165 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1166 if (support[s] < cMax) { 1167 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 1168 er = GetTriMidEdgeInverse_Static(ornt[c], r); 1169 if (er == eint[c]) { 1170 intFaces += 1; 1171 } else { 1172 intFaces += 2; 1173 } 1174 } else { 1175 intFaces += 1; 1176 } 1177 } 1178 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 1179 } 1180 } 1181 /* Interior cell edges have 2 vertices and 4 faces */ 1182 for (c = cStart; c < cMax; ++c) { 1183 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 1184 1185 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1186 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1187 } 1188 /* Hybrid edges have 2 vertices and the same faces */ 1189 for (e = eMax; e < eEnd; ++e) { 1190 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 1191 PetscInt size; 1192 1193 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1194 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1195 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1196 } 1197 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 1198 for (f = fMax; f < fEnd; ++f) { 1199 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 1200 PetscInt size; 1201 1202 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1203 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1204 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 1205 } 1206 /* Interior vertices have identical supports */ 1207 for (v = vStart; v < vEnd; ++v) { 1208 const PetscInt newp = vStartNew + (v - vStart); 1209 PetscInt size; 1210 1211 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1212 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1213 } 1214 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 1215 for (e = eStart; e < eMax; ++e) { 1216 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1217 const PetscInt *support; 1218 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 1219 1220 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1221 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1222 for (s = 0; s < size; ++s) { 1223 if (support[s] < fMax) faceSize += 2; 1224 else faceSize += 1; 1225 } 1226 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1227 for (s = 0; s < starSize*2; s += 2) { 1228 const PetscInt *cone, *ornt; 1229 PetscInt e01, e23; 1230 1231 if ((star[s] >= cStart) && (star[s] < cMax)) { 1232 /* Check edge 0-1 */ 1233 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1234 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1235 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1236 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1237 /* Check edge 2-3 */ 1238 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1239 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1240 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1241 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1242 if ((e01 == e) || (e23 == e)) ++cellSize; 1243 } 1244 } 1245 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1246 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 1247 } 1248 break; 1249 case REFINER_SIMPLEX_TO_HEX_3D: 1250 /* All cells have 6 faces */ 1251 for (c = cStart; c < cEnd; ++c) { 1252 for (r = 0; r < 4; ++r) { 1253 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1254 1255 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1256 } 1257 } 1258 /* Split faces have 4 edges and the same cells as the parent */ 1259 for (f = fStart; f < fEnd; ++f) { 1260 for (r = 0; r < 3; ++r) { 1261 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1262 PetscInt size; 1263 1264 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1265 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1266 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1267 } 1268 } 1269 /* Interior cell faces have 4 edges and 2 cells */ 1270 for (c = cStart; c < cEnd; ++c) { 1271 for (r = 0; r < 6; ++r) { 1272 const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r; 1273 1274 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1275 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1276 } 1277 } 1278 /* Split edges have 2 vertices and the same faces */ 1279 for (e = eStart; e < eEnd; ++e) { 1280 for (r = 0; r < 2; ++r) { 1281 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1282 PetscInt size; 1283 1284 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1285 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1286 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1287 } 1288 } 1289 /* Face edges have 2 vertices and 2 + cell faces supports */ 1290 for (f = fStart; f < fEnd; ++f) { 1291 for (r = 0; r < 3; ++r) { 1292 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1293 PetscInt size; 1294 1295 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1296 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1297 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1298 } 1299 } 1300 /* Interior cell edges have 2 vertices and 3 faces */ 1301 for (c = cStart; c < cEnd; ++c) { 1302 for (r = 0; r < 4; ++r) { 1303 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 1304 1305 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1306 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1307 } 1308 } 1309 /* Old vertices have identical supports */ 1310 for (v = vStart; v < vEnd; ++v) { 1311 const PetscInt newp = vStartNew + (v - vStart); 1312 PetscInt size; 1313 1314 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1315 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1316 } 1317 /* Edge vertices have 2 + faces supports */ 1318 for (e = eStart; e < eEnd; ++e) { 1319 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1320 PetscInt size; 1321 1322 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1323 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1324 } 1325 /* Face vertices have 3 + cells supports */ 1326 for (f = fStart; f < fEnd; ++f) { 1327 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 1328 PetscInt size; 1329 1330 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1331 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1332 } 1333 /* Interior cell vertices have 4 supports */ 1334 for (c = cStart; c < cEnd; ++c) { 1335 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart; 1336 1337 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1338 } 1339 break; 1340 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 1341 /* the mesh is no longer hybrid */ 1342 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1343 cMax = PetscMin(cEnd, cMax); 1344 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1345 fMax = PetscMin(fEnd, fMax); 1346 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 1347 eMax = PetscMin(eEnd, eMax); 1348 /* All cells have 6 faces */ 1349 for (c = cStart; c < cMax; ++c) { 1350 for (r = 0; r < 4; ++r) { 1351 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1352 1353 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1354 } 1355 } 1356 for (c = cMax; c < cEnd; ++c) { 1357 for (r = 0; r < 3; ++r) { 1358 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + r; 1359 1360 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1361 } 1362 } 1363 /* Interior split faces have 4 edges and the same cells as the parent */ 1364 for (f = fStart; f < fMax; ++f) { 1365 for (r = 0; r < 3; ++r) { 1366 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1367 PetscInt size; 1368 1369 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1370 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1371 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1372 } 1373 } 1374 /* Interior cell faces have 4 edges and 2 cells */ 1375 for (c = cStart; c < cMax; ++c) { 1376 for (r = 0; r < 6; ++r) { 1377 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + r; 1378 1379 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1380 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1381 } 1382 } 1383 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1384 for (f = fMax; f < fEnd; ++f) { 1385 for (r = 0; r < 2; ++r) { 1386 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2 + r; 1387 PetscInt size; 1388 1389 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1390 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1391 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1392 } 1393 } 1394 /* Hybrid cell faces have 4 edges and 2 cells */ 1395 for (c = cMax; c < cEnd; ++c) { 1396 for (r = 0; r < 3; ++r) { 1397 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1398 1399 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1400 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1401 } 1402 } 1403 /* Interior split edges have 2 vertices and the same faces */ 1404 for (e = eStart; e < eMax; ++e) { 1405 for (r = 0; r < 2; ++r) { 1406 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1407 PetscInt size; 1408 1409 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1410 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1411 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1412 } 1413 } 1414 /* Interior face edges have 2 vertices and 2 + cell faces supports */ 1415 for (f = fStart; f < fMax; ++f) { 1416 for (r = 0; r < 3; ++r) { 1417 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1418 PetscInt size; 1419 1420 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1421 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1422 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1423 } 1424 } 1425 /* Interior cell edges have 2 vertices and 3 faces */ 1426 for (c = cStart; c < cMax; ++c) { 1427 for (r = 0; r < 4; ++r) { 1428 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 1429 1430 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1431 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1432 } 1433 } 1434 /* Hybrid edges have 2 vertices and the same faces */ 1435 for (e = eMax; e < eEnd; ++e) { 1436 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 1437 PetscInt size; 1438 1439 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1440 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1441 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1442 } 1443 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1444 for (f = fMax; f < fEnd; ++f) { 1445 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 1446 PetscInt size; 1447 1448 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1449 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1450 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1451 } 1452 /* Hybrid cell edges have 2 vertices and 3 faces */ 1453 for (c = cMax; c < cEnd; ++c) { 1454 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1455 1456 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1457 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1458 } 1459 /* Old vertices have identical supports */ 1460 for (v = vStart; v < vEnd; ++v) { 1461 const PetscInt newp = vStartNew + (v - vStart); 1462 PetscInt size; 1463 1464 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1465 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1466 } 1467 /* Interior edge vertices have 2 + faces supports */ 1468 for (e = eStart; e < eMax; ++e) { 1469 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1470 PetscInt size; 1471 1472 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1473 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1474 } 1475 /* Interior face vertices have 3 + cells supports */ 1476 for (f = fStart; f < fMax; ++f) { 1477 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 1478 PetscInt size; 1479 1480 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1481 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1482 } 1483 /* Interior cell vertices have 4 supports */ 1484 for (c = cStart; c < cMax; ++c) { 1485 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 1486 1487 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1488 } 1489 break; 1490 case REFINER_HEX_3D: 1491 /* All cells have 6 faces */ 1492 for (c = cStart; c < cEnd; ++c) { 1493 for (r = 0; r < 8; ++r) { 1494 const PetscInt newp = (c - cStart)*8 + r; 1495 1496 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1497 } 1498 } 1499 /* Split faces have 4 edges and the same cells as the parent */ 1500 for (f = fStart; f < fEnd; ++f) { 1501 for (r = 0; r < 4; ++r) { 1502 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1503 PetscInt size; 1504 1505 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1506 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1507 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1508 } 1509 } 1510 /* Interior faces have 4 edges and 2 cells */ 1511 for (c = cStart; c < cEnd; ++c) { 1512 for (r = 0; r < 12; ++r) { 1513 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 1514 1515 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1516 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1517 } 1518 } 1519 /* Split edges have 2 vertices and the same faces as the parent */ 1520 for (e = eStart; e < eEnd; ++e) { 1521 for (r = 0; r < 2; ++r) { 1522 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1523 PetscInt size; 1524 1525 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1526 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1527 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1528 } 1529 } 1530 /* Face edges have 2 vertices and 2+cells faces */ 1531 for (f = fStart; f < fEnd; ++f) { 1532 for (r = 0; r < 4; ++r) { 1533 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 1534 PetscInt size; 1535 1536 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1537 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1538 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1539 } 1540 } 1541 /* Cell edges have 2 vertices and 4 faces */ 1542 for (c = cStart; c < cEnd; ++c) { 1543 for (r = 0; r < 6; ++r) { 1544 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 1545 1546 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1547 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1548 } 1549 } 1550 /* Old vertices have identical supports */ 1551 for (v = vStart; v < vEnd; ++v) { 1552 const PetscInt newp = vStartNew + (v - vStart); 1553 PetscInt size; 1554 1555 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1556 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1557 } 1558 /* Edge vertices have 2 + faces supports */ 1559 for (e = eStart; e < eEnd; ++e) { 1560 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1561 PetscInt size; 1562 1563 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1564 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1565 } 1566 /* Face vertices have 4 + cells supports */ 1567 for (f = fStart; f < fEnd; ++f) { 1568 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 1569 PetscInt size; 1570 1571 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1572 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1573 } 1574 /* Cell vertices have 6 supports */ 1575 for (c = cStart; c < cEnd; ++c) { 1576 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 1577 1578 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1579 } 1580 break; 1581 case REFINER_HYBRID_HEX_3D: 1582 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 1583 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1584 /* Interior cells have 6 faces */ 1585 for (c = cStart; c < cMax; ++c) { 1586 for (r = 0; r < 8; ++r) { 1587 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1588 1589 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1590 } 1591 } 1592 /* Hybrid cells have 6 faces */ 1593 for (c = cMax; c < cEnd; ++c) { 1594 for (r = 0; r < 4; ++r) { 1595 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1596 1597 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1598 } 1599 } 1600 /* Interior split faces have 4 edges and the same cells as the parent */ 1601 for (f = fStart; f < fMax; ++f) { 1602 for (r = 0; r < 4; ++r) { 1603 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1604 PetscInt size; 1605 1606 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1607 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1608 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1609 } 1610 } 1611 /* Interior cell faces have 4 edges and 2 cells */ 1612 for (c = cStart; c < cMax; ++c) { 1613 for (r = 0; r < 12; ++r) { 1614 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1615 1616 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1617 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1618 } 1619 } 1620 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1621 for (f = fMax; f < fEnd; ++f) { 1622 for (r = 0; r < 2; ++r) { 1623 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1624 PetscInt size; 1625 1626 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1627 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1628 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1629 } 1630 } 1631 /* Hybrid cells faces have 4 edges and 2 cells */ 1632 for (c = cMax; c < cEnd; ++c) { 1633 for (r = 0; r < 4; ++r) { 1634 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1635 1636 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1637 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1638 } 1639 } 1640 /* Interior split edges have 2 vertices and the same faces as the parent */ 1641 for (e = eStart; e < eMax; ++e) { 1642 for (r = 0; r < 2; ++r) { 1643 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1644 PetscInt size; 1645 1646 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1647 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1648 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1649 } 1650 } 1651 /* Interior face edges have 2 vertices and 2+cells faces */ 1652 for (f = fStart; f < fMax; ++f) { 1653 for (r = 0; r < 4; ++r) { 1654 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1655 PetscInt size; 1656 1657 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1658 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1659 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1660 } 1661 } 1662 /* Interior cell edges have 2 vertices and 4 faces */ 1663 for (c = cStart; c < cMax; ++c) { 1664 for (r = 0; r < 6; ++r) { 1665 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1666 1667 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1668 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1669 } 1670 } 1671 /* Hybrid edges have 2 vertices and the same faces */ 1672 for (e = eMax; e < eEnd; ++e) { 1673 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1674 PetscInt size; 1675 1676 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1677 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1678 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1679 } 1680 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1681 for (f = fMax; f < fEnd; ++f) { 1682 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1683 PetscInt size; 1684 1685 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1686 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1687 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1688 } 1689 /* Hybrid cell edges have 2 vertices and 4 faces */ 1690 for (c = cMax; c < cEnd; ++c) { 1691 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1692 1693 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1694 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1695 } 1696 /* Interior vertices have identical supports */ 1697 for (v = vStart; v < vEnd; ++v) { 1698 const PetscInt newp = vStartNew + (v - vStart); 1699 PetscInt size; 1700 1701 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1702 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1703 } 1704 /* Interior edge vertices have 2 + faces supports */ 1705 for (e = eStart; e < eMax; ++e) { 1706 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1707 PetscInt size; 1708 1709 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1710 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1711 } 1712 /* Interior face vertices have 4 + cells supports */ 1713 for (f = fStart; f < fMax; ++f) { 1714 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1715 PetscInt size; 1716 1717 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1718 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1719 } 1720 /* Interior cell vertices have 6 supports */ 1721 for (c = cStart; c < cMax; ++c) { 1722 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1723 1724 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1725 } 1726 break; 1727 default: 1728 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 1729 } 1730 PetscFunctionReturn(0); 1731 } 1732 1733 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1734 { 1735 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1736 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1737 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1738 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r; 1739 #if defined(PETSC_USE_DEBUG) 1740 PetscInt p; 1741 #endif 1742 PetscErrorCode ierr; 1743 1744 PetscFunctionBegin; 1745 if (!refiner) PetscFunctionReturn(0); 1746 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1747 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1748 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1749 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1750 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1751 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1752 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1753 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1754 switch (refiner) { 1755 case REFINER_SIMPLEX_1D: 1756 /* Max support size of refined mesh is 2 */ 1757 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1758 /* All cells have 2 vertices */ 1759 for (c = cStart; c < cEnd; ++c) { 1760 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1761 1762 for (r = 0; r < 2; ++r) { 1763 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1764 const PetscInt *cone; 1765 PetscInt coneNew[2]; 1766 1767 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1768 coneNew[0] = vStartNew + (cone[0] - vStart); 1769 coneNew[1] = vStartNew + (cone[1] - vStart); 1770 coneNew[(r+1)%2] = newv; 1771 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1772 #if defined(PETSC_USE_DEBUG) 1773 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp, cStartNew, cEndNew); 1774 for (p = 0; p < 2; ++p) { 1775 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); 1776 } 1777 #endif 1778 } 1779 } 1780 /* Old vertices have identical supports */ 1781 for (v = vStart; v < vEnd; ++v) { 1782 const PetscInt newp = vStartNew + (v - vStart); 1783 const PetscInt *support, *cone; 1784 PetscInt size, s; 1785 1786 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1787 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1788 for (s = 0; s < size; ++s) { 1789 PetscInt r = 0; 1790 1791 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1792 if (cone[1] == v) r = 1; 1793 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1794 } 1795 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1796 #if defined(PETSC_USE_DEBUG) 1797 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1798 for (p = 0; p < size; ++p) { 1799 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); 1800 } 1801 #endif 1802 } 1803 /* Cell vertices have support of 2 cells */ 1804 for (c = cStart; c < cEnd; ++c) { 1805 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1806 1807 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1808 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1809 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1810 #if defined(PETSC_USE_DEBUG) 1811 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1812 for (p = 0; p < 2; ++p) { 1813 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); 1814 } 1815 #endif 1816 } 1817 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1818 break; 1819 case REFINER_SIMPLEX_2D: 1820 /* 1821 2 1822 |\ 1823 | \ 1824 | \ 1825 | \ 1826 | C \ 1827 | \ 1828 | \ 1829 2---1---1 1830 |\ D / \ 1831 | 2 0 \ 1832 |A \ / B \ 1833 0---0-------1 1834 */ 1835 /* All cells have 3 faces */ 1836 for (c = cStart; c < cEnd; ++c) { 1837 const PetscInt newp = cStartNew + (c - cStart)*4; 1838 const PetscInt *cone, *ornt; 1839 PetscInt coneNew[3], orntNew[3]; 1840 1841 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1842 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1843 /* A triangle */ 1844 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1845 orntNew[0] = ornt[0]; 1846 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1847 orntNew[1] = -2; 1848 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1849 orntNew[2] = ornt[2]; 1850 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1851 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1852 #if defined(PETSC_USE_DEBUG) 1853 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); 1854 for (p = 0; p < 3; ++p) { 1855 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); 1856 } 1857 #endif 1858 /* B triangle */ 1859 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1860 orntNew[0] = ornt[0]; 1861 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1862 orntNew[1] = ornt[1]; 1863 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1864 orntNew[2] = -2; 1865 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1866 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1867 #if defined(PETSC_USE_DEBUG) 1868 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); 1869 for (p = 0; p < 3; ++p) { 1870 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); 1871 } 1872 #endif 1873 /* C triangle */ 1874 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1875 orntNew[0] = -2; 1876 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1877 orntNew[1] = ornt[1]; 1878 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1879 orntNew[2] = ornt[2]; 1880 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1881 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1882 #if defined(PETSC_USE_DEBUG) 1883 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); 1884 for (p = 0; p < 3; ++p) { 1885 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); 1886 } 1887 #endif 1888 /* D triangle */ 1889 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1890 orntNew[0] = 0; 1891 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1892 orntNew[1] = 0; 1893 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1894 orntNew[2] = 0; 1895 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1896 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1897 #if defined(PETSC_USE_DEBUG) 1898 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); 1899 for (p = 0; p < 3; ++p) { 1900 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); 1901 } 1902 #endif 1903 } 1904 /* Split faces have 2 vertices and the same cells as the parent */ 1905 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1906 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1907 for (f = fStart; f < fEnd; ++f) { 1908 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1909 1910 for (r = 0; r < 2; ++r) { 1911 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1912 const PetscInt *cone, *ornt, *support; 1913 PetscInt coneNew[2], coneSize, c, supportSize, s; 1914 1915 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1916 coneNew[0] = vStartNew + (cone[0] - vStart); 1917 coneNew[1] = vStartNew + (cone[1] - vStart); 1918 coneNew[(r+1)%2] = newv; 1919 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1920 #if defined(PETSC_USE_DEBUG) 1921 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1922 for (p = 0; p < 2; ++p) { 1923 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); 1924 } 1925 #endif 1926 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1927 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1928 for (s = 0; s < supportSize; ++s) { 1929 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1930 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1931 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1932 for (c = 0; c < coneSize; ++c) { 1933 if (cone[c] == f) break; 1934 } 1935 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1936 } 1937 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1938 #if defined(PETSC_USE_DEBUG) 1939 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1940 for (p = 0; p < supportSize; ++p) { 1941 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); 1942 } 1943 #endif 1944 } 1945 } 1946 /* Interior faces have 2 vertices and 2 cells */ 1947 for (c = cStart; c < cEnd; ++c) { 1948 const PetscInt *cone; 1949 1950 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1951 for (r = 0; r < 3; ++r) { 1952 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1953 PetscInt coneNew[2]; 1954 PetscInt supportNew[2]; 1955 1956 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1957 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1958 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1959 #if defined(PETSC_USE_DEBUG) 1960 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1961 for (p = 0; p < 2; ++p) { 1962 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); 1963 } 1964 #endif 1965 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1966 supportNew[1] = (c - cStart)*4 + 3; 1967 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1968 #if defined(PETSC_USE_DEBUG) 1969 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1970 for (p = 0; p < 2; ++p) { 1971 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); 1972 } 1973 #endif 1974 } 1975 } 1976 /* Old vertices have identical supports */ 1977 for (v = vStart; v < vEnd; ++v) { 1978 const PetscInt newp = vStartNew + (v - vStart); 1979 const PetscInt *support, *cone; 1980 PetscInt size, s; 1981 1982 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1983 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1984 for (s = 0; s < size; ++s) { 1985 PetscInt r = 0; 1986 1987 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1988 if (cone[1] == v) r = 1; 1989 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1990 } 1991 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1992 #if defined(PETSC_USE_DEBUG) 1993 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1994 for (p = 0; p < size; ++p) { 1995 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); 1996 } 1997 #endif 1998 } 1999 /* Face vertices have 2 + cells*2 supports */ 2000 for (f = fStart; f < fEnd; ++f) { 2001 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2002 const PetscInt *cone, *support; 2003 PetscInt size, s; 2004 2005 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2006 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2007 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2008 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2009 for (s = 0; s < size; ++s) { 2010 PetscInt r = 0; 2011 2012 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2013 if (cone[1] == f) r = 1; 2014 else if (cone[2] == f) r = 2; 2015 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 2016 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2017 } 2018 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2019 #if defined(PETSC_USE_DEBUG) 2020 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2021 for (p = 0; p < 2+size*2; ++p) { 2022 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); 2023 } 2024 #endif 2025 } 2026 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2027 break; 2028 case REFINER_SIMPLEX_TO_HEX_2D: 2029 /* 2030 2 2031 |\ 2032 | \ 2033 | \ 2034 | \ 2035 | C \ 2036 | \ 2037 2 1 2038 |\ / \ 2039 | 2 1 \ 2040 | \/ \ 2041 | | \ 2042 |A | B \ 2043 | 0 \ 2044 | | \ 2045 0---0----------1 2046 */ 2047 /* All cells have 4 faces */ 2048 for (c = cStart; c < cEnd; ++c) { 2049 const PetscInt newp = cStartNew + (c - cStart)*3; 2050 const PetscInt *cone, *ornt; 2051 PetscInt coneNew[4], orntNew[4]; 2052 2053 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2054 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2055 /* A quad */ 2056 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2057 orntNew[0] = ornt[0]; 2058 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2059 orntNew[1] = 0; 2060 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2061 orntNew[2] = -2; 2062 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2063 orntNew[3] = ornt[2]; 2064 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2065 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2066 #if defined(PETSC_USE_DEBUG) 2067 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); 2068 for (p = 0; p < 4; ++p) { 2069 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); 2070 } 2071 #endif 2072 /* B quad */ 2073 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2074 orntNew[0] = ornt[0]; 2075 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2076 orntNew[1] = ornt[1]; 2077 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2078 orntNew[2] = 0; 2079 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2080 orntNew[3] = -2; 2081 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2082 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2083 #if defined(PETSC_USE_DEBUG) 2084 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); 2085 for (p = 0; p < 4; ++p) { 2086 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); 2087 } 2088 #endif 2089 /* C quad */ 2090 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2091 orntNew[0] = ornt[1]; 2092 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2093 orntNew[1] = ornt[2]; 2094 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2095 orntNew[2] = 0; 2096 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2097 orntNew[3] = -2; 2098 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2099 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2100 #if defined(PETSC_USE_DEBUG) 2101 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); 2102 for (p = 0; p < 4; ++p) { 2103 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); 2104 } 2105 #endif 2106 } 2107 /* Split faces have 2 vertices and the same cells as the parent */ 2108 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2109 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2110 for (f = fStart; f < fEnd; ++f) { 2111 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2112 2113 for (r = 0; r < 2; ++r) { 2114 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2115 const PetscInt *cone, *ornt, *support; 2116 PetscInt coneNew[2], coneSize, c, supportSize, s; 2117 2118 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2119 coneNew[0] = vStartNew + (cone[0] - vStart); 2120 coneNew[1] = vStartNew + (cone[1] - vStart); 2121 coneNew[(r+1)%2] = newv; 2122 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2123 #if defined(PETSC_USE_DEBUG) 2124 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2125 for (p = 0; p < 2; ++p) { 2126 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); 2127 } 2128 #endif 2129 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2130 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2131 for (s = 0; s < supportSize; ++s) { 2132 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2133 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2134 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2135 for (c = 0; c < coneSize; ++c) { 2136 if (cone[c] == f) break; 2137 } 2138 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2139 } 2140 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2141 #if defined(PETSC_USE_DEBUG) 2142 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2143 for (p = 0; p < supportSize; ++p) { 2144 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); 2145 } 2146 #endif 2147 } 2148 } 2149 /* Interior faces have 2 vertices and 2 cells */ 2150 for (c = cStart; c < cEnd; ++c) { 2151 const PetscInt *cone; 2152 2153 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2154 for (r = 0; r < 3; ++r) { 2155 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2156 PetscInt coneNew[2]; 2157 PetscInt supportNew[2]; 2158 2159 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2160 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2161 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2162 #if defined(PETSC_USE_DEBUG) 2163 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2164 for (p = 0; p < 2; ++p) { 2165 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); 2166 } 2167 #endif 2168 supportNew[0] = (c - cStart)*3 + r%3; 2169 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2170 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2171 #if defined(PETSC_USE_DEBUG) 2172 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2173 for (p = 0; p < 2; ++p) { 2174 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); 2175 } 2176 #endif 2177 } 2178 } 2179 /* Old vertices have identical supports */ 2180 for (v = vStart; v < vEnd; ++v) { 2181 const PetscInt newp = vStartNew + (v - vStart); 2182 const PetscInt *support, *cone; 2183 PetscInt size, s; 2184 2185 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2186 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2187 for (s = 0; s < size; ++s) { 2188 PetscInt r = 0; 2189 2190 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2191 if (cone[1] == v) r = 1; 2192 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2193 } 2194 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2195 #if defined(PETSC_USE_DEBUG) 2196 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2197 for (p = 0; p < size; ++p) { 2198 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); 2199 } 2200 #endif 2201 } 2202 /* Split-face vertices have cells + 2 supports */ 2203 for (f = fStart; f < fEnd; ++f) { 2204 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2205 const PetscInt *cone, *support; 2206 PetscInt size, s; 2207 2208 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2209 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2210 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2211 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2212 for (s = 0; s < size; ++s) { 2213 PetscInt r = 0; 2214 2215 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2216 if (cone[1] == f) r = 1; 2217 else if (cone[2] == f) r = 2; 2218 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2219 } 2220 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2221 #if defined(PETSC_USE_DEBUG) 2222 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2223 for (p = 0; p < 2+size; ++p) { 2224 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); 2225 } 2226 #endif 2227 } 2228 /* Interior vertices have 3 supports */ 2229 for (c = cStart; c < cEnd; ++c) { 2230 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2231 2232 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2233 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2234 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2235 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2236 } 2237 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2238 break; 2239 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 2240 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2241 cMax = PetscMin(cEnd, cMax); 2242 for (c = cStart; c < cMax; ++c) { 2243 const PetscInt newp = cStartNew + (c - cStart)*3; 2244 const PetscInt *cone, *ornt; 2245 PetscInt coneNew[4], orntNew[4]; 2246 2247 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2248 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2249 /* A quad */ 2250 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2251 orntNew[0] = ornt[0]; 2252 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2253 orntNew[1] = 0; 2254 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2255 orntNew[2] = -2; 2256 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2257 orntNew[3] = ornt[2]; 2258 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2259 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2260 #if defined(PETSC_USE_DEBUG) 2261 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); 2262 for (p = 0; p < 4; ++p) { 2263 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); 2264 } 2265 #endif 2266 /* B quad */ 2267 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2268 orntNew[0] = ornt[0]; 2269 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2270 orntNew[1] = ornt[1]; 2271 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2272 orntNew[2] = 0; 2273 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2274 orntNew[3] = -2; 2275 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2276 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2277 #if defined(PETSC_USE_DEBUG) 2278 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); 2279 for (p = 0; p < 4; ++p) { 2280 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); 2281 } 2282 #endif 2283 /* C quad */ 2284 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2285 orntNew[0] = ornt[1]; 2286 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2287 orntNew[1] = ornt[2]; 2288 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2289 orntNew[2] = 0; 2290 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2291 orntNew[3] = -2; 2292 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2293 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2294 #if defined(PETSC_USE_DEBUG) 2295 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); 2296 for (p = 0; p < 4; ++p) { 2297 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); 2298 } 2299 #endif 2300 } 2301 /* 2302 2---------1---------3 2303 | | | 2304 | D 1 C | 2305 | | | 2306 2----2----0----3----3 2307 | | | 2308 | A 0 B | 2309 | | | 2310 0---------0---------1 2311 */ 2312 /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */ 2313 for (c = cMax; c < cEnd; ++c) { 2314 const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4; 2315 const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4; 2316 const PetscInt *cone, *ornt; 2317 PetscInt coneNew[4], orntNew[4]; 2318 2319 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2320 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2321 /* A quad */ 2322 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2323 orntNew[0] = ornt[0]; 2324 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2325 orntNew[1] = 0; 2326 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2327 orntNew[2] = -2; 2328 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2329 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2330 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2331 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2332 #if defined(PETSC_USE_DEBUG) 2333 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); 2334 for (p = 0; p < 4; ++p) { 2335 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); 2336 } 2337 #endif 2338 /* B quad */ 2339 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2340 orntNew[0] = ornt[0]; 2341 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2342 orntNew[1] = ornt[3]; 2343 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2344 orntNew[2] = 0; 2345 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2346 orntNew[3] = -2; 2347 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2348 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2349 #if defined(PETSC_USE_DEBUG) 2350 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); 2351 for (p = 0; p < 4; ++p) { 2352 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); 2353 } 2354 #endif 2355 /* C quad */ 2356 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2357 orntNew[0] = -2; 2358 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2359 orntNew[1] = ornt[3]; 2360 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2361 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2362 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2363 orntNew[3] = 0; 2364 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2365 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2366 #if defined(PETSC_USE_DEBUG) 2367 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); 2368 for (p = 0; p < 4; ++p) { 2369 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); 2370 } 2371 #endif 2372 /* D quad */ 2373 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2374 orntNew[0] = 0; 2375 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2376 orntNew[1] = -2; 2377 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2378 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2379 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2380 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2381 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2382 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2383 #if defined(PETSC_USE_DEBUG) 2384 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); 2385 for (p = 0; p < 4; ++p) { 2386 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); 2387 } 2388 #endif 2389 } 2390 /* Split faces have 2 vertices and the same cells as the parent */ 2391 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2392 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2393 for (f = fStart; f < fEnd; ++f) { 2394 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2395 2396 for (r = 0; r < 2; ++r) { 2397 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2398 const PetscInt *cone, *ornt, *support; 2399 PetscInt coneNew[2], coneSize, c, supportSize, s; 2400 2401 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2402 coneNew[0] = vStartNew + (cone[0] - vStart); 2403 coneNew[1] = vStartNew + (cone[1] - vStart); 2404 coneNew[(r+1)%2] = newv; 2405 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2406 #if defined(PETSC_USE_DEBUG) 2407 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2408 for (p = 0; p < 2; ++p) { 2409 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); 2410 } 2411 #endif 2412 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2413 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2414 for (s = 0; s < supportSize; ++s) { 2415 const PetscInt p2q[4][2] = { {0, 1}, 2416 {3, 2}, 2417 {0, 3}, 2418 {1, 2} }; 2419 2420 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2421 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2422 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2423 for (c = 0; c < coneSize; ++c) { 2424 if (cone[c] == f) break; 2425 } 2426 if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2427 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]); 2428 else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2429 } 2430 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2431 #if defined(PETSC_USE_DEBUG) 2432 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2433 for (p = 0; p < supportSize; ++p) { 2434 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); 2435 } 2436 #endif 2437 } 2438 } 2439 /* Interior faces have 2 vertices and 2 cells */ 2440 for (c = cStart; c < cMax; ++c) { 2441 const PetscInt *cone; 2442 2443 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2444 for (r = 0; r < 3; ++r) { 2445 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2446 PetscInt coneNew[2]; 2447 PetscInt supportNew[2]; 2448 2449 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2450 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2451 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2452 #if defined(PETSC_USE_DEBUG) 2453 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2454 for (p = 0; p < 2; ++p) { 2455 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); 2456 } 2457 #endif 2458 supportNew[0] = (c - cStart)*3 + r%3; 2459 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2460 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2461 #if defined(PETSC_USE_DEBUG) 2462 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2463 for (p = 0; p < 2; ++p) { 2464 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); 2465 } 2466 #endif 2467 } 2468 } 2469 /* Hybrid interior faces have 2 vertices and 2 cells */ 2470 for (c = cMax; c < cEnd; ++c) { 2471 const PetscInt *cone; 2472 PetscInt coneNew[2], supportNew[2]; 2473 2474 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2475 for (r = 0; r < 4; ++r) { 2476 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 2477 2478 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2479 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax); 2480 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2481 #if defined(PETSC_USE_DEBUG) 2482 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2483 for (p = 0; p < 2; ++p) { 2484 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); 2485 } 2486 #endif 2487 if (r==0) { 2488 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2489 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2490 } else if (r==1) { 2491 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2492 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2493 } else if (r==2) { 2494 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2495 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2496 } else { 2497 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2498 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2499 } 2500 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2501 #if defined(PETSC_USE_DEBUG) 2502 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2503 for (p = 0; p < 2; ++p) { 2504 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); 2505 } 2506 #endif 2507 } 2508 } 2509 /* Old vertices have identical supports */ 2510 for (v = vStart; v < vEnd; ++v) { 2511 const PetscInt newp = vStartNew + (v - vStart); 2512 const PetscInt *support, *cone; 2513 PetscInt size, s; 2514 2515 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2516 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2517 for (s = 0; s < size; ++s) { 2518 PetscInt r = 0; 2519 2520 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2521 if (cone[1] == v) r = 1; 2522 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2523 } 2524 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2525 #if defined(PETSC_USE_DEBUG) 2526 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2527 for (p = 0; p < size; ++p) { 2528 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); 2529 } 2530 #endif 2531 } 2532 /* Split-face vertices have cells + 2 supports */ 2533 for (f = fStart; f < fEnd; ++f) { 2534 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2535 const PetscInt *cone, *support; 2536 PetscInt size, s; 2537 2538 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2539 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2540 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2541 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2542 for (s = 0; s < size; ++s) { 2543 PetscInt r = 0, coneSize; 2544 2545 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2546 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2547 if (coneSize == 3) { 2548 if (cone[1] == f) r = 1; 2549 else if (cone[2] == f) r = 2; 2550 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2551 } else if (coneSize == 4) { 2552 if (cone[1] == f) r = 1; 2553 else if (cone[2] == f) r = 2; 2554 else if (cone[3] == f) r = 3; 2555 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r; 2556 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2557 } 2558 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2559 #if defined(PETSC_USE_DEBUG) 2560 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2561 for (p = 0; p < 2+size; ++p) { 2562 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); 2563 } 2564 #endif 2565 } 2566 /* Interior vertices have 3 supports */ 2567 for (c = cStart; c < cMax; ++c) { 2568 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2569 2570 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2571 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2572 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2573 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2574 } 2575 /* Hybrid interior vertices have 4 supports */ 2576 for (c = cMax; c < cEnd; ++c) { 2577 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2578 2579 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0; 2580 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1; 2581 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2; 2582 supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3; 2583 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2584 } 2585 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2586 break; 2587 case REFINER_HEX_2D: 2588 /* 2589 3---------2---------2 2590 | | | 2591 | D 2 C | 2592 | | | 2593 3----3----0----1----1 2594 | | | 2595 | A 0 B | 2596 | | | 2597 0---------0---------1 2598 */ 2599 /* All cells have 4 faces */ 2600 for (c = cStart; c < cEnd; ++c) { 2601 const PetscInt newp = (c - cStart)*4; 2602 const PetscInt *cone, *ornt; 2603 PetscInt coneNew[4], orntNew[4]; 2604 2605 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2606 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2607 /* A quad */ 2608 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2609 orntNew[0] = ornt[0]; 2610 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2611 orntNew[1] = 0; 2612 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2613 orntNew[2] = -2; 2614 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2615 orntNew[3] = ornt[3]; 2616 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2617 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2618 #if defined(PETSC_USE_DEBUG) 2619 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); 2620 for (p = 0; p < 4; ++p) { 2621 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); 2622 } 2623 #endif 2624 /* B quad */ 2625 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2626 orntNew[0] = ornt[0]; 2627 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2628 orntNew[1] = ornt[1]; 2629 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2630 orntNew[2] = -2; 2631 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2632 orntNew[3] = -2; 2633 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2634 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2635 #if defined(PETSC_USE_DEBUG) 2636 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); 2637 for (p = 0; p < 4; ++p) { 2638 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); 2639 } 2640 #endif 2641 /* C quad */ 2642 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2643 orntNew[0] = 0; 2644 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2645 orntNew[1] = ornt[1]; 2646 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2647 orntNew[2] = ornt[2]; 2648 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2649 orntNew[3] = -2; 2650 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2651 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2652 #if defined(PETSC_USE_DEBUG) 2653 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); 2654 for (p = 0; p < 4; ++p) { 2655 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); 2656 } 2657 #endif 2658 /* D quad */ 2659 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2660 orntNew[0] = 0; 2661 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2662 orntNew[1] = 0; 2663 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2664 orntNew[2] = ornt[2]; 2665 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2666 orntNew[3] = ornt[3]; 2667 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2668 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2669 #if defined(PETSC_USE_DEBUG) 2670 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); 2671 for (p = 0; p < 4; ++p) { 2672 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); 2673 } 2674 #endif 2675 } 2676 /* Split faces have 2 vertices and the same cells as the parent */ 2677 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2678 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2679 for (f = fStart; f < fEnd; ++f) { 2680 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2681 2682 for (r = 0; r < 2; ++r) { 2683 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2684 const PetscInt *cone, *ornt, *support; 2685 PetscInt coneNew[2], coneSize, c, supportSize, s; 2686 2687 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2688 coneNew[0] = vStartNew + (cone[0] - vStart); 2689 coneNew[1] = vStartNew + (cone[1] - vStart); 2690 coneNew[(r+1)%2] = newv; 2691 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2692 #if defined(PETSC_USE_DEBUG) 2693 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2694 for (p = 0; p < 2; ++p) { 2695 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); 2696 } 2697 #endif 2698 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2699 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2700 for (s = 0; s < supportSize; ++s) { 2701 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2702 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2703 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2704 for (c = 0; c < coneSize; ++c) { 2705 if (cone[c] == f) break; 2706 } 2707 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2708 } 2709 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2710 #if defined(PETSC_USE_DEBUG) 2711 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2712 for (p = 0; p < supportSize; ++p) { 2713 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); 2714 } 2715 #endif 2716 } 2717 } 2718 /* Interior faces have 2 vertices and 2 cells */ 2719 for (c = cStart; c < cEnd; ++c) { 2720 const PetscInt *cone; 2721 PetscInt coneNew[2], supportNew[2]; 2722 2723 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2724 for (r = 0; r < 4; ++r) { 2725 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2726 2727 if (r==1 || r==2) { 2728 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2729 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2730 } else { 2731 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2732 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2733 } 2734 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2735 #if defined(PETSC_USE_DEBUG) 2736 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2737 for (p = 0; p < 2; ++p) { 2738 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); 2739 } 2740 #endif 2741 supportNew[0] = (c - cStart)*4 + r; 2742 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2743 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2744 #if defined(PETSC_USE_DEBUG) 2745 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2746 for (p = 0; p < 2; ++p) { 2747 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); 2748 } 2749 #endif 2750 } 2751 } 2752 /* Old vertices have identical supports */ 2753 for (v = vStart; v < vEnd; ++v) { 2754 const PetscInt newp = vStartNew + (v - vStart); 2755 const PetscInt *support, *cone; 2756 PetscInt size, s; 2757 2758 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2759 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2760 for (s = 0; s < size; ++s) { 2761 PetscInt r = 0; 2762 2763 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2764 if (cone[1] == v) r = 1; 2765 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2766 } 2767 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2768 #if defined(PETSC_USE_DEBUG) 2769 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2770 for (p = 0; p < size; ++p) { 2771 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); 2772 } 2773 #endif 2774 } 2775 /* Face vertices have 2 + cells supports */ 2776 for (f = fStart; f < fEnd; ++f) { 2777 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2778 const PetscInt *cone, *support; 2779 PetscInt size, s; 2780 2781 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2782 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2783 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2784 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2785 for (s = 0; s < size; ++s) { 2786 PetscInt r = 0; 2787 2788 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2789 if (cone[1] == f) r = 1; 2790 else if (cone[2] == f) r = 2; 2791 else if (cone[3] == f) r = 3; 2792 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 2793 } 2794 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2795 #if defined(PETSC_USE_DEBUG) 2796 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2797 for (p = 0; p < 2+size; ++p) { 2798 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); 2799 } 2800 #endif 2801 } 2802 /* Cell vertices have 4 supports */ 2803 for (c = cStart; c < cEnd; ++c) { 2804 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2805 PetscInt supportNew[4]; 2806 2807 for (r = 0; r < 4; ++r) { 2808 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2809 } 2810 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2811 } 2812 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2813 break; 2814 case REFINER_HYBRID_SIMPLEX_2D: 2815 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2816 cMax = PetscMin(cEnd, cMax); 2817 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2818 fMax = PetscMin(fEnd, fMax); 2819 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2820 /* Interior cells have 3 faces */ 2821 for (c = cStart; c < cMax; ++c) { 2822 const PetscInt newp = cStartNew + (c - cStart)*4; 2823 const PetscInt *cone, *ornt; 2824 PetscInt coneNew[3], orntNew[3]; 2825 2826 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2827 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2828 /* A triangle */ 2829 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2830 orntNew[0] = ornt[0]; 2831 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2832 orntNew[1] = -2; 2833 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2834 orntNew[2] = ornt[2]; 2835 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2836 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2837 #if defined(PETSC_USE_DEBUG) 2838 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); 2839 for (p = 0; p < 3; ++p) { 2840 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); 2841 } 2842 #endif 2843 /* B triangle */ 2844 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2845 orntNew[0] = ornt[0]; 2846 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2847 orntNew[1] = ornt[1]; 2848 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2849 orntNew[2] = -2; 2850 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2851 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2852 #if defined(PETSC_USE_DEBUG) 2853 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); 2854 for (p = 0; p < 3; ++p) { 2855 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); 2856 } 2857 #endif 2858 /* C triangle */ 2859 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2860 orntNew[0] = -2; 2861 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2862 orntNew[1] = ornt[1]; 2863 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2864 orntNew[2] = ornt[2]; 2865 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2866 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2867 #if defined(PETSC_USE_DEBUG) 2868 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); 2869 for (p = 0; p < 3; ++p) { 2870 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); 2871 } 2872 #endif 2873 /* D triangle */ 2874 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2875 orntNew[0] = 0; 2876 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2877 orntNew[1] = 0; 2878 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2879 orntNew[2] = 0; 2880 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2881 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2882 #if defined(PETSC_USE_DEBUG) 2883 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); 2884 for (p = 0; p < 3; ++p) { 2885 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); 2886 } 2887 #endif 2888 } 2889 /* 2890 2----3----3 2891 | | 2892 | B | 2893 | | 2894 0----4--- 1 2895 | | 2896 | A | 2897 | | 2898 0----2----1 2899 */ 2900 /* Hybrid cells have 4 faces */ 2901 for (c = cMax; c < cEnd; ++c) { 2902 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2903 const PetscInt *cone, *ornt; 2904 PetscInt coneNew[4], orntNew[4], r; 2905 2906 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2907 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2908 r = (ornt[0] < 0 ? 1 : 0); 2909 /* A quad */ 2910 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2911 orntNew[0] = ornt[0]; 2912 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2913 orntNew[1] = ornt[1]; 2914 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2915 orntNew[2+r] = 0; 2916 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2917 orntNew[3-r] = 0; 2918 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2919 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2920 #if defined(PETSC_USE_DEBUG) 2921 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); 2922 for (p = 0; p < 4; ++p) { 2923 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); 2924 } 2925 #endif 2926 /* B quad */ 2927 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2928 orntNew[0] = ornt[0]; 2929 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2930 orntNew[1] = ornt[1]; 2931 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2932 orntNew[2+r] = 0; 2933 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2934 orntNew[3-r] = 0; 2935 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2936 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2937 #if defined(PETSC_USE_DEBUG) 2938 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); 2939 for (p = 0; p < 4; ++p) { 2940 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); 2941 } 2942 #endif 2943 } 2944 /* Interior split faces have 2 vertices and the same cells as the parent */ 2945 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2946 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2947 for (f = fStart; f < fMax; ++f) { 2948 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2949 2950 for (r = 0; r < 2; ++r) { 2951 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2952 const PetscInt *cone, *ornt, *support; 2953 PetscInt coneNew[2], coneSize, c, supportSize, s; 2954 2955 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2956 coneNew[0] = vStartNew + (cone[0] - vStart); 2957 coneNew[1] = vStartNew + (cone[1] - vStart); 2958 coneNew[(r+1)%2] = newv; 2959 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2960 #if defined(PETSC_USE_DEBUG) 2961 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2962 for (p = 0; p < 2; ++p) { 2963 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); 2964 } 2965 #endif 2966 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2967 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2968 for (s = 0; s < supportSize; ++s) { 2969 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2970 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2971 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2972 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2973 if (support[s] >= cMax) { 2974 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2975 } else { 2976 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2977 } 2978 } 2979 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2980 #if defined(PETSC_USE_DEBUG) 2981 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2982 for (p = 0; p < supportSize; ++p) { 2983 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); 2984 } 2985 #endif 2986 } 2987 } 2988 /* Interior cell faces have 2 vertices and 2 cells */ 2989 for (c = cStart; c < cMax; ++c) { 2990 const PetscInt *cone; 2991 2992 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2993 for (r = 0; r < 3; ++r) { 2994 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 2995 PetscInt coneNew[2]; 2996 PetscInt supportNew[2]; 2997 2998 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2999 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 3000 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3001 #if defined(PETSC_USE_DEBUG) 3002 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3003 for (p = 0; p < 2; ++p) { 3004 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); 3005 } 3006 #endif 3007 supportNew[0] = (c - cStart)*4 + (r+1)%3; 3008 supportNew[1] = (c - cStart)*4 + 3; 3009 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3010 #if defined(PETSC_USE_DEBUG) 3011 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3012 for (p = 0; p < 2; ++p) { 3013 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3014 } 3015 #endif 3016 } 3017 } 3018 /* Interior hybrid faces have 2 vertices and the same cells */ 3019 for (f = fMax; f < fEnd; ++f) { 3020 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 3021 const PetscInt *cone, *ornt; 3022 const PetscInt *support; 3023 PetscInt coneNew[2]; 3024 PetscInt supportNew[2]; 3025 PetscInt size, s, r; 3026 3027 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3028 coneNew[0] = vStartNew + (cone[0] - vStart); 3029 coneNew[1] = vStartNew + (cone[1] - vStart); 3030 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3031 #if defined(PETSC_USE_DEBUG) 3032 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3033 for (p = 0; p < 2; ++p) { 3034 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); 3035 } 3036 #endif 3037 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3038 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3039 for (s = 0; s < size; ++s) { 3040 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3041 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3042 for (r = 0; r < 2; ++r) { 3043 if (cone[r+2] == f) break; 3044 } 3045 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 3046 } 3047 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3048 #if defined(PETSC_USE_DEBUG) 3049 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3050 for (p = 0; p < size; ++p) { 3051 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); 3052 } 3053 #endif 3054 } 3055 /* Cell hybrid faces have 2 vertices and 2 cells */ 3056 for (c = cMax; c < cEnd; ++c) { 3057 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 3058 const PetscInt *cone; 3059 PetscInt coneNew[2]; 3060 PetscInt supportNew[2]; 3061 3062 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3063 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3064 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3065 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3066 #if defined(PETSC_USE_DEBUG) 3067 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3068 for (p = 0; p < 2; ++p) { 3069 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); 3070 } 3071 #endif 3072 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3073 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3074 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3075 #if defined(PETSC_USE_DEBUG) 3076 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3077 for (p = 0; p < 2; ++p) { 3078 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); 3079 } 3080 #endif 3081 } 3082 /* Old vertices have identical supports */ 3083 for (v = vStart; v < vEnd; ++v) { 3084 const PetscInt newp = vStartNew + (v - vStart); 3085 const PetscInt *support, *cone; 3086 PetscInt size, s; 3087 3088 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3089 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3090 for (s = 0; s < size; ++s) { 3091 if (support[s] >= fMax) { 3092 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 3093 } else { 3094 PetscInt r = 0; 3095 3096 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3097 if (cone[1] == v) r = 1; 3098 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3099 } 3100 } 3101 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3102 #if defined(PETSC_USE_DEBUG) 3103 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3104 for (p = 0; p < size; ++p) { 3105 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); 3106 } 3107 #endif 3108 } 3109 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 3110 for (f = fStart; f < fMax; ++f) { 3111 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3112 const PetscInt *cone, *support; 3113 PetscInt size, newSize = 2, s; 3114 3115 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3116 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3117 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3118 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3119 for (s = 0; s < size; ++s) { 3120 PetscInt r = 0; 3121 3122 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3123 if (support[s] >= cMax) { 3124 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 3125 3126 newSize += 1; 3127 } else { 3128 if (cone[1] == f) r = 1; 3129 else if (cone[2] == f) r = 2; 3130 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 3131 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 3132 3133 newSize += 2; 3134 } 3135 } 3136 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3137 #if defined(PETSC_USE_DEBUG) 3138 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3139 for (p = 0; p < newSize; ++p) { 3140 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); 3141 } 3142 #endif 3143 } 3144 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3145 break; 3146 case REFINER_HYBRID_HEX_2D: 3147 /* Hybrid Hex 2D */ 3148 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 3149 cMax = PetscMin(cEnd, cMax); 3150 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 3151 fMax = PetscMin(fEnd, fMax); 3152 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 3153 /* Interior cells have 4 faces */ 3154 for (c = cStart; c < cMax; ++c) { 3155 const PetscInt newp = cStartNew + (c - cStart)*4; 3156 const PetscInt *cone, *ornt; 3157 PetscInt coneNew[4], orntNew[4]; 3158 3159 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3160 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3161 /* A quad */ 3162 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3163 orntNew[0] = ornt[0]; 3164 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3165 orntNew[1] = 0; 3166 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3167 orntNew[2] = -2; 3168 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 3169 orntNew[3] = ornt[3]; 3170 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3171 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3172 #if defined(PETSC_USE_DEBUG) 3173 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); 3174 for (p = 0; p < 4; ++p) { 3175 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); 3176 } 3177 #endif 3178 /* B quad */ 3179 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3180 orntNew[0] = ornt[0]; 3181 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3182 orntNew[1] = ornt[1]; 3183 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3184 orntNew[2] = 0; 3185 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3186 orntNew[3] = -2; 3187 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3188 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3189 #if defined(PETSC_USE_DEBUG) 3190 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); 3191 for (p = 0; p < 4; ++p) { 3192 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); 3193 } 3194 #endif 3195 /* C quad */ 3196 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3197 orntNew[0] = -2; 3198 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3199 orntNew[1] = ornt[1]; 3200 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 3201 orntNew[2] = ornt[2]; 3202 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3203 orntNew[3] = 0; 3204 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3205 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3206 #if defined(PETSC_USE_DEBUG) 3207 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); 3208 for (p = 0; p < 4; ++p) { 3209 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); 3210 } 3211 #endif 3212 /* D quad */ 3213 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3214 orntNew[0] = 0; 3215 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3216 orntNew[1] = -2; 3217 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 3218 orntNew[2] = ornt[2]; 3219 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 3220 orntNew[3] = ornt[3]; 3221 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3222 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3223 #if defined(PETSC_USE_DEBUG) 3224 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); 3225 for (p = 0; p < 4; ++p) { 3226 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); 3227 } 3228 #endif 3229 } 3230 /* 3231 2----3----3 3232 | | 3233 | B | 3234 | | 3235 0----4--- 1 3236 | | 3237 | A | 3238 | | 3239 0----2----1 3240 */ 3241 /* Hybrid cells have 4 faces */ 3242 for (c = cMax; c < cEnd; ++c) { 3243 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 3244 const PetscInt *cone, *ornt; 3245 PetscInt coneNew[4], orntNew[4]; 3246 3247 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3248 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3249 /* A quad */ 3250 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3251 orntNew[0] = ornt[0]; 3252 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3253 orntNew[1] = ornt[1]; 3254 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 3255 orntNew[2] = 0; 3256 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3257 orntNew[3] = 0; 3258 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3259 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3260 #if defined(PETSC_USE_DEBUG) 3261 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); 3262 for (p = 0; p < 4; ++p) { 3263 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); 3264 } 3265 #endif 3266 /* B quad */ 3267 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3268 orntNew[0] = ornt[0]; 3269 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3270 orntNew[1] = ornt[1]; 3271 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3272 orntNew[2] = 0; 3273 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 3274 orntNew[3] = 0; 3275 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3276 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3277 #if defined(PETSC_USE_DEBUG) 3278 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); 3279 for (p = 0; p < 4; ++p) { 3280 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); 3281 } 3282 #endif 3283 } 3284 /* Interior split faces have 2 vertices and the same cells as the parent */ 3285 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3286 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3287 for (f = fStart; f < fMax; ++f) { 3288 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 3289 3290 for (r = 0; r < 2; ++r) { 3291 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 3292 const PetscInt *cone, *ornt, *support; 3293 PetscInt coneNew[2], coneSize, c, supportSize, s; 3294 3295 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3296 coneNew[0] = vStartNew + (cone[0] - vStart); 3297 coneNew[1] = vStartNew + (cone[1] - vStart); 3298 coneNew[(r+1)%2] = newv; 3299 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3300 #if defined(PETSC_USE_DEBUG) 3301 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3302 for (p = 0; p < 2; ++p) { 3303 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); 3304 } 3305 #endif 3306 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3307 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3308 for (s = 0; s < supportSize; ++s) { 3309 if (support[s] >= cMax) { 3310 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3311 } else { 3312 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3313 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3314 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3315 for (c = 0; c < coneSize; ++c) { 3316 if (cone[c] == f) break; 3317 } 3318 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3319 } 3320 } 3321 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3322 #if defined(PETSC_USE_DEBUG) 3323 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3324 for (p = 0; p < supportSize; ++p) { 3325 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); 3326 } 3327 #endif 3328 } 3329 } 3330 /* Interior cell faces have 2 vertices and 2 cells */ 3331 for (c = cStart; c < cMax; ++c) { 3332 const PetscInt *cone; 3333 3334 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3335 for (r = 0; r < 4; ++r) { 3336 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3337 PetscInt coneNew[2], supportNew[2]; 3338 3339 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3340 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3341 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3342 #if defined(PETSC_USE_DEBUG) 3343 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3344 for (p = 0; p < 2; ++p) { 3345 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); 3346 } 3347 #endif 3348 supportNew[0] = (c - cStart)*4 + r; 3349 supportNew[1] = (c - cStart)*4 + (r+1)%4; 3350 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3351 #if defined(PETSC_USE_DEBUG) 3352 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3353 for (p = 0; p < 2; ++p) { 3354 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); 3355 } 3356 #endif 3357 } 3358 } 3359 /* Hybrid faces have 2 vertices and the same cells */ 3360 for (f = fMax; f < fEnd; ++f) { 3361 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 3362 const PetscInt *cone, *support; 3363 PetscInt coneNew[2], supportNew[2]; 3364 PetscInt size, s, r; 3365 3366 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3367 coneNew[0] = vStartNew + (cone[0] - vStart); 3368 coneNew[1] = vStartNew + (cone[1] - vStart); 3369 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3370 #if defined(PETSC_USE_DEBUG) 3371 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3372 for (p = 0; p < 2; ++p) { 3373 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); 3374 } 3375 #endif 3376 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3377 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3378 for (s = 0; s < size; ++s) { 3379 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3380 for (r = 0; r < 2; ++r) { 3381 if (cone[r+2] == f) break; 3382 } 3383 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3384 } 3385 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3386 #if defined(PETSC_USE_DEBUG) 3387 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3388 for (p = 0; p < size; ++p) { 3389 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); 3390 } 3391 #endif 3392 } 3393 /* Cell hybrid faces have 2 vertices and 2 cells */ 3394 for (c = cMax; c < cEnd; ++c) { 3395 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3396 const PetscInt *cone; 3397 PetscInt coneNew[2], supportNew[2]; 3398 3399 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3400 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3401 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3402 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3403 #if defined(PETSC_USE_DEBUG) 3404 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3405 for (p = 0; p < 2; ++p) { 3406 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); 3407 } 3408 #endif 3409 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3410 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3411 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3412 #if defined(PETSC_USE_DEBUG) 3413 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3414 for (p = 0; p < 2; ++p) { 3415 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); 3416 } 3417 #endif 3418 } 3419 /* Old vertices have identical supports */ 3420 for (v = vStart; v < vEnd; ++v) { 3421 const PetscInt newp = vStartNew + (v - vStart); 3422 const PetscInt *support, *cone; 3423 PetscInt size, s; 3424 3425 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3426 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3427 for (s = 0; s < size; ++s) { 3428 if (support[s] >= fMax) { 3429 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 3430 } else { 3431 PetscInt r = 0; 3432 3433 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3434 if (cone[1] == v) r = 1; 3435 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3436 } 3437 } 3438 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3439 #if defined(PETSC_USE_DEBUG) 3440 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3441 for (p = 0; p < size; ++p) { 3442 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); 3443 } 3444 #endif 3445 } 3446 /* Face vertices have 2 + cells supports */ 3447 for (f = fStart; f < fMax; ++f) { 3448 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3449 const PetscInt *cone, *support; 3450 PetscInt size, s; 3451 3452 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3453 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3454 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3455 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3456 for (s = 0; s < size; ++s) { 3457 PetscInt r = 0; 3458 3459 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3460 if (support[s] >= cMax) { 3461 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 3462 } else { 3463 if (cone[1] == f) r = 1; 3464 else if (cone[2] == f) r = 2; 3465 else if (cone[3] == f) r = 3; 3466 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 3467 } 3468 } 3469 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3470 #if defined(PETSC_USE_DEBUG) 3471 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3472 for (p = 0; p < 2+size; ++p) { 3473 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); 3474 } 3475 #endif 3476 } 3477 /* Cell vertices have 4 supports */ 3478 for (c = cStart; c < cMax; ++c) { 3479 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3480 PetscInt supportNew[4]; 3481 3482 for (r = 0; r < 4; ++r) { 3483 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3484 } 3485 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3486 } 3487 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3488 break; 3489 case REFINER_SIMPLEX_3D: 3490 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3491 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3492 for (c = cStart; c < cEnd; ++c) { 3493 const PetscInt newp = cStartNew + (c - cStart)*8; 3494 const PetscInt *cone, *ornt; 3495 PetscInt coneNew[4], orntNew[4]; 3496 3497 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3498 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3499 /* A tetrahedron: {0, a, c, d} */ 3500 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3501 orntNew[0] = ornt[0]; 3502 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3503 orntNew[1] = ornt[1]; 3504 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3505 orntNew[2] = ornt[2]; 3506 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3507 orntNew[3] = 0; 3508 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3509 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3510 #if defined(PETSC_USE_DEBUG) 3511 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); 3512 for (p = 0; p < 4; ++p) { 3513 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); 3514 } 3515 #endif 3516 /* B tetrahedron: {a, 1, b, e} */ 3517 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3518 orntNew[0] = ornt[0]; 3519 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3520 orntNew[1] = ornt[1]; 3521 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3522 orntNew[2] = 0; 3523 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3524 orntNew[3] = ornt[3]; 3525 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3526 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3527 #if defined(PETSC_USE_DEBUG) 3528 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); 3529 for (p = 0; p < 4; ++p) { 3530 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); 3531 } 3532 #endif 3533 /* C tetrahedron: {c, b, 2, f} */ 3534 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3535 orntNew[0] = ornt[0]; 3536 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3537 orntNew[1] = 0; 3538 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3539 orntNew[2] = ornt[2]; 3540 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3541 orntNew[3] = ornt[3]; 3542 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3543 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3544 #if defined(PETSC_USE_DEBUG) 3545 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); 3546 for (p = 0; p < 4; ++p) { 3547 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); 3548 } 3549 #endif 3550 /* D tetrahedron: {d, e, f, 3} */ 3551 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3552 orntNew[0] = 0; 3553 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3554 orntNew[1] = ornt[1]; 3555 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3556 orntNew[2] = ornt[2]; 3557 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3558 orntNew[3] = ornt[3]; 3559 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3560 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3561 #if defined(PETSC_USE_DEBUG) 3562 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); 3563 for (p = 0; p < 4; ++p) { 3564 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); 3565 } 3566 #endif 3567 /* A' tetrahedron: {c, d, a, f} */ 3568 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3569 orntNew[0] = -3; 3570 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3571 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3572 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3573 orntNew[2] = 0; 3574 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3575 orntNew[3] = 2; 3576 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3577 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3578 #if defined(PETSC_USE_DEBUG) 3579 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); 3580 for (p = 0; p < 4; ++p) { 3581 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); 3582 } 3583 #endif 3584 /* B' tetrahedron: {e, b, a, f} */ 3585 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3586 orntNew[0] = -2; 3587 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 3588 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 3589 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3590 orntNew[2] = 0; 3591 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3592 orntNew[3] = 0; 3593 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3594 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3595 #if defined(PETSC_USE_DEBUG) 3596 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); 3597 for (p = 0; p < 4; ++p) { 3598 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); 3599 } 3600 #endif 3601 /* C' tetrahedron: {f, a, c, b} */ 3602 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3603 orntNew[0] = -2; 3604 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3605 orntNew[1] = -2; 3606 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3607 orntNew[2] = -1; 3608 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 3609 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3610 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3611 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3612 #if defined(PETSC_USE_DEBUG) 3613 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); 3614 for (p = 0; p < 4; ++p) { 3615 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); 3616 } 3617 #endif 3618 /* D' tetrahedron: {f, a, e, d} */ 3619 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3620 orntNew[0] = -2; 3621 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3622 orntNew[1] = -1; 3623 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3624 orntNew[2] = -2; 3625 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 3626 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 3627 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3628 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3629 #if defined(PETSC_USE_DEBUG) 3630 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); 3631 for (p = 0; p < 4; ++p) { 3632 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); 3633 } 3634 #endif 3635 } 3636 /* Split faces have 3 edges and the same cells as the parent */ 3637 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3638 ierr = PetscMalloc1(2 + maxSupportSize*3, &supportRef);CHKERRQ(ierr); 3639 for (f = fStart; f < fEnd; ++f) { 3640 const PetscInt newp = fStartNew + (f - fStart)*4; 3641 const PetscInt *cone, *ornt, *support; 3642 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3643 3644 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3645 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3646 /* A triangle */ 3647 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3648 orntNew[0] = ornt[0]; 3649 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3650 orntNew[1] = -2; 3651 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3652 orntNew[2] = ornt[2]; 3653 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3654 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3655 #if defined(PETSC_USE_DEBUG) 3656 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); 3657 for (p = 0; p < 3; ++p) { 3658 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); 3659 } 3660 #endif 3661 /* B triangle */ 3662 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3663 orntNew[0] = ornt[0]; 3664 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3665 orntNew[1] = ornt[1]; 3666 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3667 orntNew[2] = -2; 3668 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3669 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3670 #if defined(PETSC_USE_DEBUG) 3671 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); 3672 for (p = 0; p < 3; ++p) { 3673 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); 3674 } 3675 #endif 3676 /* C triangle */ 3677 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3678 orntNew[0] = -2; 3679 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3680 orntNew[1] = ornt[1]; 3681 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3682 orntNew[2] = ornt[2]; 3683 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3684 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3685 #if defined(PETSC_USE_DEBUG) 3686 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); 3687 for (p = 0; p < 3; ++p) { 3688 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); 3689 } 3690 #endif 3691 /* D triangle */ 3692 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3693 orntNew[0] = 0; 3694 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3695 orntNew[1] = 0; 3696 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3697 orntNew[2] = 0; 3698 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3699 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3700 #if defined(PETSC_USE_DEBUG) 3701 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); 3702 for (p = 0; p < 3; ++p) { 3703 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); 3704 } 3705 #endif 3706 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3707 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3708 for (r = 0; r < 4; ++r) { 3709 for (s = 0; s < supportSize; ++s) { 3710 PetscInt subf; 3711 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3712 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3713 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3714 for (c = 0; c < coneSize; ++c) { 3715 if (cone[c] == f) break; 3716 } 3717 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3718 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3719 } 3720 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3721 #if defined(PETSC_USE_DEBUG) 3722 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); 3723 for (p = 0; p < supportSize; ++p) { 3724 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); 3725 } 3726 #endif 3727 } 3728 } 3729 /* Interior faces have 3 edges and 2 cells */ 3730 for (c = cStart; c < cEnd; ++c) { 3731 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 3732 const PetscInt *cone, *ornt; 3733 PetscInt coneNew[3], orntNew[3]; 3734 PetscInt supportNew[2]; 3735 3736 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3737 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3738 /* Face A: {c, a, d} */ 3739 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3740 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3741 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3742 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3743 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3744 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3745 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3746 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3747 #if defined(PETSC_USE_DEBUG) 3748 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3749 for (p = 0; p < 3; ++p) { 3750 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); 3751 } 3752 #endif 3753 supportNew[0] = (c - cStart)*8 + 0; 3754 supportNew[1] = (c - cStart)*8 + 0+4; 3755 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3756 #if defined(PETSC_USE_DEBUG) 3757 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3758 for (p = 0; p < 2; ++p) { 3759 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); 3760 } 3761 #endif 3762 ++newp; 3763 /* Face B: {a, b, e} */ 3764 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3765 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3766 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3767 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3768 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3769 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3770 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3771 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3772 #if defined(PETSC_USE_DEBUG) 3773 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3774 for (p = 0; p < 3; ++p) { 3775 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); 3776 } 3777 #endif 3778 supportNew[0] = (c - cStart)*8 + 1; 3779 supportNew[1] = (c - cStart)*8 + 1+4; 3780 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3781 #if defined(PETSC_USE_DEBUG) 3782 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3783 for (p = 0; p < 2; ++p) { 3784 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); 3785 } 3786 #endif 3787 ++newp; 3788 /* Face C: {c, f, b} */ 3789 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3790 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3791 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3792 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3793 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3794 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3795 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3796 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3797 #if defined(PETSC_USE_DEBUG) 3798 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3799 for (p = 0; p < 3; ++p) { 3800 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); 3801 } 3802 #endif 3803 supportNew[0] = (c - cStart)*8 + 2; 3804 supportNew[1] = (c - cStart)*8 + 2+4; 3805 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3806 #if defined(PETSC_USE_DEBUG) 3807 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3808 for (p = 0; p < 2; ++p) { 3809 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); 3810 } 3811 #endif 3812 ++newp; 3813 /* Face D: {d, e, f} */ 3814 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3815 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3816 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3817 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3818 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3819 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3820 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3821 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3822 #if defined(PETSC_USE_DEBUG) 3823 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3824 for (p = 0; p < 3; ++p) { 3825 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); 3826 } 3827 #endif 3828 supportNew[0] = (c - cStart)*8 + 3; 3829 supportNew[1] = (c - cStart)*8 + 3+4; 3830 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3831 #if defined(PETSC_USE_DEBUG) 3832 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3833 for (p = 0; p < 2; ++p) { 3834 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); 3835 } 3836 #endif 3837 ++newp; 3838 /* Face E: {d, f, a} */ 3839 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3840 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3841 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3842 orntNew[1] = -2; 3843 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3844 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3845 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3846 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3847 #if defined(PETSC_USE_DEBUG) 3848 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3849 for (p = 0; p < 3; ++p) { 3850 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); 3851 } 3852 #endif 3853 supportNew[0] = (c - cStart)*8 + 0+4; 3854 supportNew[1] = (c - cStart)*8 + 3+4; 3855 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3856 #if defined(PETSC_USE_DEBUG) 3857 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3858 for (p = 0; p < 2; ++p) { 3859 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); 3860 } 3861 #endif 3862 ++newp; 3863 /* Face F: {c, a, f} */ 3864 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3865 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3866 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3867 orntNew[1] = 0; 3868 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3869 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3870 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3871 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3872 #if defined(PETSC_USE_DEBUG) 3873 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3874 for (p = 0; p < 3; ++p) { 3875 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); 3876 } 3877 #endif 3878 supportNew[0] = (c - cStart)*8 + 0+4; 3879 supportNew[1] = (c - cStart)*8 + 2+4; 3880 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3881 #if defined(PETSC_USE_DEBUG) 3882 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3883 for (p = 0; p < 2; ++p) { 3884 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); 3885 } 3886 #endif 3887 ++newp; 3888 /* Face G: {e, a, f} */ 3889 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3890 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3891 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3892 orntNew[1] = 0; 3893 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3894 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3895 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3896 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3897 #if defined(PETSC_USE_DEBUG) 3898 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3899 for (p = 0; p < 3; ++p) { 3900 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); 3901 } 3902 #endif 3903 supportNew[0] = (c - cStart)*8 + 1+4; 3904 supportNew[1] = (c - cStart)*8 + 3+4; 3905 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3906 #if defined(PETSC_USE_DEBUG) 3907 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3908 for (p = 0; p < 2; ++p) { 3909 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); 3910 } 3911 #endif 3912 ++newp; 3913 /* Face H: {a, b, f} */ 3914 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3915 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3916 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3917 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3918 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3919 orntNew[2] = -2; 3920 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3921 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3922 #if defined(PETSC_USE_DEBUG) 3923 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3924 for (p = 0; p < 3; ++p) { 3925 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); 3926 } 3927 #endif 3928 supportNew[0] = (c - cStart)*8 + 1+4; 3929 supportNew[1] = (c - cStart)*8 + 2+4; 3930 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3931 #if defined(PETSC_USE_DEBUG) 3932 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3933 for (p = 0; p < 2; ++p) { 3934 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); 3935 } 3936 #endif 3937 ++newp; 3938 } 3939 /* Split Edges have 2 vertices and the same faces as the parent */ 3940 for (e = eStart; e < eEnd; ++e) { 3941 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3942 3943 for (r = 0; r < 2; ++r) { 3944 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3945 const PetscInt *cone, *ornt, *support; 3946 PetscInt coneNew[2], coneSize, c, supportSize, s; 3947 3948 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3949 coneNew[0] = vStartNew + (cone[0] - vStart); 3950 coneNew[1] = vStartNew + (cone[1] - vStart); 3951 coneNew[(r+1)%2] = newv; 3952 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3953 #if defined(PETSC_USE_DEBUG) 3954 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3955 for (p = 0; p < 2; ++p) { 3956 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); 3957 } 3958 #endif 3959 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3960 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3961 for (s = 0; s < supportSize; ++s) { 3962 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3963 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3964 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3965 for (c = 0; c < coneSize; ++c) { 3966 if (cone[c] == e) break; 3967 } 3968 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3969 } 3970 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3971 #if defined(PETSC_USE_DEBUG) 3972 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3973 for (p = 0; p < supportSize; ++p) { 3974 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); 3975 } 3976 #endif 3977 } 3978 } 3979 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3980 for (f = fStart; f < fEnd; ++f) { 3981 const PetscInt *cone, *ornt, *support; 3982 PetscInt coneSize, supportSize, s; 3983 3984 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3985 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3986 for (r = 0; r < 3; ++r) { 3987 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3988 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3989 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3990 -1, -1, 1, 6, 0, 4, 3991 2, 5, 3, 4, -1, -1, 3992 -1, -1, 3, 6, 2, 7}; 3993 3994 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3995 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 3996 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 3997 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3998 #if defined(PETSC_USE_DEBUG) 3999 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4000 for (p = 0; p < 2; ++p) { 4001 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); 4002 } 4003 #endif 4004 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4005 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4006 for (s = 0; s < supportSize; ++s) { 4007 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4008 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4009 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4010 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4011 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4012 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4013 if (er == eint[c]) { 4014 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4015 } else { 4016 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4017 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4018 } 4019 } 4020 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4021 #if defined(PETSC_USE_DEBUG) 4022 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4023 for (p = 0; p < intFaces; ++p) { 4024 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); 4025 } 4026 #endif 4027 } 4028 } 4029 /* Interior edges have 2 vertices and 4 faces */ 4030 for (c = cStart; c < cEnd; ++c) { 4031 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 4032 const PetscInt *cone, *ornt, *fcone; 4033 PetscInt coneNew[2], supportNew[4], find; 4034 4035 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4036 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4037 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4038 find = GetTriEdge_Static(ornt[0], 0); 4039 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4040 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4041 find = GetTriEdge_Static(ornt[2], 1); 4042 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4043 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4044 #if defined(PETSC_USE_DEBUG) 4045 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4046 for (p = 0; p < 2; ++p) { 4047 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); 4048 } 4049 #endif 4050 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 4051 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 4052 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 4053 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 4054 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4055 #if defined(PETSC_USE_DEBUG) 4056 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4057 for (p = 0; p < 4; ++p) { 4058 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); 4059 } 4060 #endif 4061 } 4062 /* Old vertices have identical supports */ 4063 for (v = vStart; v < vEnd; ++v) { 4064 const PetscInt newp = vStartNew + (v - vStart); 4065 const PetscInt *support, *cone; 4066 PetscInt size, s; 4067 4068 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4069 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4070 for (s = 0; s < size; ++s) { 4071 PetscInt r = 0; 4072 4073 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4074 if (cone[1] == v) r = 1; 4075 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4076 } 4077 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4078 #if defined(PETSC_USE_DEBUG) 4079 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4080 for (p = 0; p < size; ++p) { 4081 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); 4082 } 4083 #endif 4084 } 4085 /* Edge vertices have 2 + face*2 + 0/1 supports */ 4086 for (e = eStart; e < eEnd; ++e) { 4087 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4088 const PetscInt *cone, *support; 4089 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 4090 4091 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4092 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4093 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4094 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4095 for (s = 0; s < size; ++s) { 4096 PetscInt r = 0; 4097 4098 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4099 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4100 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4101 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4102 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4103 } 4104 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4105 for (s = 0; s < starSize*2; s += 2) { 4106 const PetscInt *cone, *ornt; 4107 PetscInt e01, e23; 4108 4109 if ((star[s] >= cStart) && (star[s] < cEnd)) { 4110 /* Check edge 0-1 */ 4111 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4112 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4113 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4114 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4115 /* Check edge 2-3 */ 4116 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4117 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4118 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4119 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4120 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 4121 } 4122 } 4123 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4124 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4125 #if defined(PETSC_USE_DEBUG) 4126 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4127 for (p = 0; p < 2+size*2+cellSize; ++p) { 4128 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); 4129 } 4130 #endif 4131 } 4132 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4133 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4134 break; 4135 case REFINER_HYBRID_SIMPLEX_3D: 4136 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4137 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 4138 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4139 for (c = cStart; c < cMax; ++c) { 4140 const PetscInt newp = cStartNew + (c - cStart)*8; 4141 const PetscInt *cone, *ornt; 4142 PetscInt coneNew[4], orntNew[4]; 4143 4144 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4145 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4146 /* A tetrahedron: {0, a, c, d} */ 4147 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 4148 orntNew[0] = ornt[0]; 4149 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 4150 orntNew[1] = ornt[1]; 4151 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 4152 orntNew[2] = ornt[2]; 4153 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4154 orntNew[3] = 0; 4155 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4156 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4157 #if defined(PETSC_USE_DEBUG) 4158 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); 4159 for (p = 0; p < 4; ++p) { 4160 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); 4161 } 4162 #endif 4163 /* B tetrahedron: {a, 1, b, e} */ 4164 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 4165 orntNew[0] = ornt[0]; 4166 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 4167 orntNew[1] = ornt[1]; 4168 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4169 orntNew[2] = 0; 4170 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 4171 orntNew[3] = ornt[3]; 4172 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4173 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4174 #if defined(PETSC_USE_DEBUG) 4175 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); 4176 for (p = 0; p < 4; ++p) { 4177 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); 4178 } 4179 #endif 4180 /* C tetrahedron: {c, b, 2, f} */ 4181 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 4182 orntNew[0] = ornt[0]; 4183 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4184 orntNew[1] = 0; 4185 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 4186 orntNew[2] = ornt[2]; 4187 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 4188 orntNew[3] = ornt[3]; 4189 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4190 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4191 #if defined(PETSC_USE_DEBUG) 4192 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); 4193 for (p = 0; p < 4; ++p) { 4194 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); 4195 } 4196 #endif 4197 /* D tetrahedron: {d, e, f, 3} */ 4198 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4199 orntNew[0] = 0; 4200 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 4201 orntNew[1] = ornt[1]; 4202 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 4203 orntNew[2] = ornt[2]; 4204 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 4205 orntNew[3] = ornt[3]; 4206 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4207 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4208 #if defined(PETSC_USE_DEBUG) 4209 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); 4210 for (p = 0; p < 4; ++p) { 4211 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); 4212 } 4213 #endif 4214 /* A' tetrahedron: {d, a, c, f} */ 4215 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4216 orntNew[0] = -3; 4217 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 4218 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 4219 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4220 orntNew[2] = 0; 4221 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4222 orntNew[3] = 2; 4223 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4224 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4225 #if defined(PETSC_USE_DEBUG) 4226 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); 4227 for (p = 0; p < 4; ++p) { 4228 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); 4229 } 4230 #endif 4231 /* B' tetrahedron: {e, b, a, f} */ 4232 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4233 orntNew[0] = -3; 4234 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4235 orntNew[1] = 1; 4236 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4237 orntNew[2] = 0; 4238 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 4239 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 4240 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4241 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4242 #if defined(PETSC_USE_DEBUG) 4243 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); 4244 for (p = 0; p < 4; ++p) { 4245 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); 4246 } 4247 #endif 4248 /* C' tetrahedron: {b, f, c, a} */ 4249 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4250 orntNew[0] = -3; 4251 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 4252 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 4253 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4254 orntNew[2] = -3; 4255 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4256 orntNew[3] = -2; 4257 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4258 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4259 #if defined(PETSC_USE_DEBUG) 4260 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); 4261 for (p = 0; p < 4; ++p) { 4262 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); 4263 } 4264 #endif 4265 /* D' tetrahedron: {f, e, d, a} */ 4266 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4267 orntNew[0] = -3; 4268 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4269 orntNew[1] = -3; 4270 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 4271 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 4272 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4273 orntNew[3] = -3; 4274 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4275 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4276 #if defined(PETSC_USE_DEBUG) 4277 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); 4278 for (p = 0; p < 4; ++p) { 4279 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); 4280 } 4281 #endif 4282 } 4283 /* Hybrid cells have 5 faces */ 4284 for (c = cMax; c < cEnd; ++c) { 4285 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 4286 const PetscInt *cone, *ornt, *fornt; 4287 PetscInt coneNew[5], orntNew[5], o, of, i; 4288 4289 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4290 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4291 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4292 o = ornt[0] < 0 ? -1 : 1; 4293 for (r = 0; r < 3; ++r) { 4294 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 4295 orntNew[0] = ornt[0]; 4296 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 4297 orntNew[1] = ornt[1]; 4298 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 4299 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 4300 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 4301 orntNew[i] = 0; 4302 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 4303 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 4304 orntNew[i] = 0; 4305 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 4306 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 4307 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); 4308 orntNew[i] = 0; 4309 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4310 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4311 #if defined(PETSC_USE_DEBUG) 4312 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); 4313 for (p = 0; p < 2; ++p) { 4314 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); 4315 } 4316 for (p = 2; p < 5; ++p) { 4317 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); 4318 } 4319 #endif 4320 } 4321 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 4322 orntNew[0] = 0; 4323 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 4324 orntNew[1] = 0; 4325 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 4326 orntNew[2] = 0; 4327 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 4328 orntNew[3] = 0; 4329 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 4330 orntNew[4] = 0; 4331 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4332 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4333 #if defined(PETSC_USE_DEBUG) 4334 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); 4335 for (p = 0; p < 2; ++p) { 4336 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); 4337 } 4338 for (p = 2; p < 5; ++p) { 4339 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); 4340 } 4341 #endif 4342 } 4343 /* Split faces have 3 edges and the same cells as the parent */ 4344 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4345 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4346 for (f = fStart; f < fMax; ++f) { 4347 const PetscInt newp = fStartNew + (f - fStart)*4; 4348 const PetscInt *cone, *ornt, *support; 4349 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 4350 4351 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4352 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4353 /* A triangle */ 4354 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4355 orntNew[0] = ornt[0]; 4356 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4357 orntNew[1] = -2; 4358 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4359 orntNew[2] = ornt[2]; 4360 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4361 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4362 #if defined(PETSC_USE_DEBUG) 4363 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); 4364 for (p = 0; p < 3; ++p) { 4365 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); 4366 } 4367 #endif 4368 /* B triangle */ 4369 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4370 orntNew[0] = ornt[0]; 4371 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4372 orntNew[1] = ornt[1]; 4373 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4374 orntNew[2] = -2; 4375 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4376 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4377 #if defined(PETSC_USE_DEBUG) 4378 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); 4379 for (p = 0; p < 3; ++p) { 4380 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); 4381 } 4382 #endif 4383 /* C triangle */ 4384 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4385 orntNew[0] = -2; 4386 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4387 orntNew[1] = ornt[1]; 4388 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4389 orntNew[2] = ornt[2]; 4390 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4391 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4392 #if defined(PETSC_USE_DEBUG) 4393 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); 4394 for (p = 0; p < 3; ++p) { 4395 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); 4396 } 4397 #endif 4398 /* D triangle */ 4399 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4400 orntNew[0] = 0; 4401 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4402 orntNew[1] = 0; 4403 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4404 orntNew[2] = 0; 4405 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4406 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4407 #if defined(PETSC_USE_DEBUG) 4408 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); 4409 for (p = 0; p < 3; ++p) { 4410 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 4411 } 4412 #endif 4413 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4414 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4415 for (r = 0; r < 4; ++r) { 4416 for (s = 0; s < supportSize; ++s) { 4417 PetscInt subf; 4418 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4419 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4420 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4421 for (c = 0; c < coneSize; ++c) { 4422 if (cone[c] == f) break; 4423 } 4424 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4425 if (support[s] < cMax) { 4426 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 4427 } else { 4428 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 4429 } 4430 } 4431 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4432 #if defined(PETSC_USE_DEBUG) 4433 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); 4434 for (p = 0; p < supportSize; ++p) { 4435 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); 4436 } 4437 #endif 4438 } 4439 } 4440 /* Interior cell faces have 3 edges and 2 cells */ 4441 for (c = cStart; c < cMax; ++c) { 4442 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 4443 const PetscInt *cone, *ornt; 4444 PetscInt coneNew[3], orntNew[3]; 4445 PetscInt supportNew[2]; 4446 4447 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4448 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4449 /* Face A: {c, a, d} */ 4450 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4451 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4452 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4453 orntNew[1] = ornt[1] < 0 ? -2 : 0; 4454 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 4455 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4456 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4457 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4458 #if defined(PETSC_USE_DEBUG) 4459 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4460 for (p = 0; p < 3; ++p) { 4461 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); 4462 } 4463 #endif 4464 supportNew[0] = (c - cStart)*8 + 0; 4465 supportNew[1] = (c - cStart)*8 + 0+4; 4466 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4467 #if defined(PETSC_USE_DEBUG) 4468 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4469 for (p = 0; p < 2; ++p) { 4470 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); 4471 } 4472 #endif 4473 ++newp; 4474 /* Face B: {a, b, e} */ 4475 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4476 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4477 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 4478 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4479 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4480 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4481 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4482 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4483 #if defined(PETSC_USE_DEBUG) 4484 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); 4485 for (p = 0; p < 3; ++p) { 4486 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); 4487 } 4488 #endif 4489 supportNew[0] = (c - cStart)*8 + 1; 4490 supportNew[1] = (c - cStart)*8 + 1+4; 4491 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4492 #if defined(PETSC_USE_DEBUG) 4493 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4494 for (p = 0; p < 2; ++p) { 4495 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); 4496 } 4497 #endif 4498 ++newp; 4499 /* Face C: {c, f, b} */ 4500 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4501 orntNew[0] = ornt[2] < 0 ? -2 : 0; 4502 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4503 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4504 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 4505 orntNew[2] = ornt[0] < 0 ? -2 : 0; 4506 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4507 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4508 #if defined(PETSC_USE_DEBUG) 4509 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4510 for (p = 0; p < 3; ++p) { 4511 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); 4512 } 4513 #endif 4514 supportNew[0] = (c - cStart)*8 + 2; 4515 supportNew[1] = (c - cStart)*8 + 2+4; 4516 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4517 #if defined(PETSC_USE_DEBUG) 4518 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4519 for (p = 0; p < 2; ++p) { 4520 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); 4521 } 4522 #endif 4523 ++newp; 4524 /* Face D: {d, e, f} */ 4525 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 4526 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4527 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4528 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4529 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4530 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4531 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4532 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4533 #if defined(PETSC_USE_DEBUG) 4534 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4535 for (p = 0; p < 3; ++p) { 4536 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); 4537 } 4538 #endif 4539 supportNew[0] = (c - cStart)*8 + 3; 4540 supportNew[1] = (c - cStart)*8 + 3+4; 4541 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4542 #if defined(PETSC_USE_DEBUG) 4543 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4544 for (p = 0; p < 2; ++p) { 4545 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); 4546 } 4547 #endif 4548 ++newp; 4549 /* Face E: {d, f, a} */ 4550 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4551 orntNew[0] = ornt[2] < 0 ? 0 : -2; 4552 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4553 orntNew[1] = -2; 4554 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4555 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4556 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4557 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4558 #if defined(PETSC_USE_DEBUG) 4559 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4560 for (p = 0; p < 3; ++p) { 4561 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); 4562 } 4563 #endif 4564 supportNew[0] = (c - cStart)*8 + 0+4; 4565 supportNew[1] = (c - cStart)*8 + 3+4; 4566 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4567 #if defined(PETSC_USE_DEBUG) 4568 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4569 for (p = 0; p < 2; ++p) { 4570 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); 4571 } 4572 #endif 4573 ++newp; 4574 /* Face F: {c, a, f} */ 4575 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4576 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4577 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4578 orntNew[1] = 0; 4579 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4580 orntNew[2] = ornt[2] < 0 ? 0 : -2; 4581 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4582 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4583 #if defined(PETSC_USE_DEBUG) 4584 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4585 for (p = 0; p < 3; ++p) { 4586 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); 4587 } 4588 #endif 4589 supportNew[0] = (c - cStart)*8 + 0+4; 4590 supportNew[1] = (c - cStart)*8 + 2+4; 4591 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4592 #if defined(PETSC_USE_DEBUG) 4593 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4594 for (p = 0; p < 2; ++p) { 4595 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); 4596 } 4597 #endif 4598 ++newp; 4599 /* Face G: {e, a, f} */ 4600 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4601 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4602 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4603 orntNew[1] = 0; 4604 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4605 orntNew[2] = ornt[3] < 0 ? 0 : -2; 4606 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4607 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4608 #if defined(PETSC_USE_DEBUG) 4609 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4610 for (p = 0; p < 3; ++p) { 4611 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); 4612 } 4613 #endif 4614 supportNew[0] = (c - cStart)*8 + 1+4; 4615 supportNew[1] = (c - cStart)*8 + 3+4; 4616 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4617 #if defined(PETSC_USE_DEBUG) 4618 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4619 for (p = 0; p < 2; ++p) { 4620 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); 4621 } 4622 #endif 4623 ++newp; 4624 /* Face H: {a, b, f} */ 4625 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4626 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4627 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4628 orntNew[1] = ornt[3] < 0 ? 0 : -2; 4629 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4630 orntNew[2] = -2; 4631 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4632 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4633 #if defined(PETSC_USE_DEBUG) 4634 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4635 for (p = 0; p < 3; ++p) { 4636 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); 4637 } 4638 #endif 4639 supportNew[0] = (c - cStart)*8 + 1+4; 4640 supportNew[1] = (c - cStart)*8 + 2+4; 4641 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4642 #if defined(PETSC_USE_DEBUG) 4643 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4644 for (p = 0; p < 2; ++p) { 4645 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); 4646 } 4647 #endif 4648 ++newp; 4649 } 4650 /* Hybrid split faces have 4 edges and same cells */ 4651 for (f = fMax; f < fEnd; ++f) { 4652 const PetscInt *cone, *ornt, *support; 4653 PetscInt coneNew[4], orntNew[4]; 4654 PetscInt supportNew[2], size, s, c; 4655 4656 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4657 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4658 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4659 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4660 for (r = 0; r < 2; ++r) { 4661 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 4662 4663 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4664 orntNew[0] = ornt[0]; 4665 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4666 orntNew[1] = ornt[1]; 4667 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 4668 orntNew[2+r] = 0; 4669 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4670 orntNew[3-r] = 0; 4671 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4672 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4673 #if defined(PETSC_USE_DEBUG) 4674 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4675 for (p = 0; p < 2; ++p) { 4676 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); 4677 } 4678 for (p = 2; p < 4; ++p) { 4679 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); 4680 } 4681 #endif 4682 for (s = 0; s < size; ++s) { 4683 const PetscInt *coneCell, *orntCell, *fornt; 4684 PetscInt o, of; 4685 4686 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4687 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4688 o = orntCell[0] < 0 ? -1 : 1; 4689 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 4690 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 4691 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4692 of = fornt[c-2] < 0 ? -1 : 1; 4693 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 4694 } 4695 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4696 #if defined(PETSC_USE_DEBUG) 4697 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4698 for (p = 0; p < size; ++p) { 4699 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); 4700 } 4701 #endif 4702 } 4703 } 4704 /* Hybrid cell faces have 4 edges and 2 cells */ 4705 for (c = cMax; c < cEnd; ++c) { 4706 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 4707 const PetscInt *cone, *ornt; 4708 PetscInt coneNew[4], orntNew[4]; 4709 PetscInt supportNew[2]; 4710 4711 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4712 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4713 for (r = 0; r < 3; ++r) { 4714 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 4715 orntNew[0] = 0; 4716 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 4717 orntNew[1] = 0; 4718 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 4719 orntNew[2] = 0; 4720 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 4721 orntNew[3] = 0; 4722 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4723 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4724 #if defined(PETSC_USE_DEBUG) 4725 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); 4726 for (p = 0; p < 2; ++p) { 4727 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); 4728 } 4729 for (p = 2; p < 4; ++p) { 4730 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); 4731 } 4732 #endif 4733 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 4734 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 4735 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4736 #if defined(PETSC_USE_DEBUG) 4737 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); 4738 for (p = 0; p < 2; ++p) { 4739 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); 4740 } 4741 #endif 4742 } 4743 } 4744 /* Interior split edges have 2 vertices and the same faces as the parent */ 4745 for (e = eStart; e < eMax; ++e) { 4746 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4747 4748 for (r = 0; r < 2; ++r) { 4749 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4750 const PetscInt *cone, *ornt, *support; 4751 PetscInt coneNew[2], coneSize, c, supportSize, s; 4752 4753 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4754 coneNew[0] = vStartNew + (cone[0] - vStart); 4755 coneNew[1] = vStartNew + (cone[1] - vStart); 4756 coneNew[(r+1)%2] = newv; 4757 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4758 #if defined(PETSC_USE_DEBUG) 4759 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4760 for (p = 0; p < 2; ++p) { 4761 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); 4762 } 4763 #endif 4764 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4765 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4766 for (s = 0; s < supportSize; ++s) { 4767 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4768 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4769 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4770 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 4771 if (support[s] < fMax) { 4772 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4773 } else { 4774 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4775 } 4776 } 4777 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4778 #if defined(PETSC_USE_DEBUG) 4779 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4780 for (p = 0; p < supportSize; ++p) { 4781 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); 4782 } 4783 #endif 4784 } 4785 } 4786 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 4787 for (f = fStart; f < fMax; ++f) { 4788 const PetscInt *cone, *ornt, *support; 4789 PetscInt coneSize, supportSize, s; 4790 4791 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4792 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4793 for (r = 0; r < 3; ++r) { 4794 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 4795 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 4796 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 4797 -1, -1, 1, 6, 0, 4, 4798 2, 5, 3, 4, -1, -1, 4799 -1, -1, 3, 6, 2, 7}; 4800 4801 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4802 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4803 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4804 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4805 #if defined(PETSC_USE_DEBUG) 4806 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4807 for (p = 0; p < 2; ++p) { 4808 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); 4809 } 4810 #endif 4811 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4812 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4813 for (s = 0; s < supportSize; ++s) { 4814 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4815 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4816 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4817 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4818 if (support[s] < cMax) { 4819 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4820 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4821 if (er == eint[c]) { 4822 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4823 } else { 4824 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4825 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4826 } 4827 } else { 4828 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4829 } 4830 } 4831 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4832 #if defined(PETSC_USE_DEBUG) 4833 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4834 for (p = 0; p < intFaces; ++p) { 4835 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); 4836 } 4837 #endif 4838 } 4839 } 4840 /* Interior cell edges have 2 vertices and 4 faces */ 4841 for (c = cStart; c < cMax; ++c) { 4842 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4843 const PetscInt *cone, *ornt, *fcone; 4844 PetscInt coneNew[2], supportNew[4], find; 4845 4846 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4847 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4848 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4849 find = GetTriEdge_Static(ornt[0], 0); 4850 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4851 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4852 find = GetTriEdge_Static(ornt[2], 1); 4853 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4854 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4855 #if defined(PETSC_USE_DEBUG) 4856 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4857 for (p = 0; p < 2; ++p) { 4858 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); 4859 } 4860 #endif 4861 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4862 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4863 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4864 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4865 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4866 #if defined(PETSC_USE_DEBUG) 4867 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4868 for (p = 0; p < 4; ++p) { 4869 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); 4870 } 4871 #endif 4872 } 4873 /* Hybrid edges have two vertices and the same faces */ 4874 for (e = eMax; e < eEnd; ++e) { 4875 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4876 const PetscInt *cone, *support, *fcone; 4877 PetscInt coneNew[2], size, fsize, s; 4878 4879 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4880 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4881 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4882 coneNew[0] = vStartNew + (cone[0] - vStart); 4883 coneNew[1] = vStartNew + (cone[1] - vStart); 4884 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4885 #if defined(PETSC_USE_DEBUG) 4886 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4887 for (p = 0; p < 2; ++p) { 4888 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); 4889 } 4890 #endif 4891 for (s = 0; s < size; ++s) { 4892 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4893 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4894 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4895 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 4896 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4897 } 4898 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4899 #if defined(PETSC_USE_DEBUG) 4900 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4901 for (p = 0; p < size; ++p) { 4902 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); 4903 } 4904 #endif 4905 } 4906 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4907 for (f = fMax; f < fEnd; ++f) { 4908 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4909 const PetscInt *cone, *support, *ccone, *cornt; 4910 PetscInt coneNew[2], size, csize, s; 4911 4912 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4913 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4914 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4915 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4916 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4917 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4918 #if defined(PETSC_USE_DEBUG) 4919 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4920 for (p = 0; p < 2; ++p) { 4921 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); 4922 } 4923 #endif 4924 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4925 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4926 for (s = 0; s < size; ++s) { 4927 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4928 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4929 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4930 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4931 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]); 4932 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4933 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4934 } 4935 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4936 #if defined(PETSC_USE_DEBUG) 4937 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4938 for (p = 0; p < 2+size*2; ++p) { 4939 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); 4940 } 4941 #endif 4942 } 4943 /* Interior vertices have identical supports */ 4944 for (v = vStart; v < vEnd; ++v) { 4945 const PetscInt newp = vStartNew + (v - vStart); 4946 const PetscInt *support, *cone; 4947 PetscInt size, s; 4948 4949 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4950 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4951 for (s = 0; s < size; ++s) { 4952 PetscInt r = 0; 4953 4954 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4955 if (cone[1] == v) r = 1; 4956 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4957 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4958 } 4959 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4960 #if defined(PETSC_USE_DEBUG) 4961 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4962 for (p = 0; p < size; ++p) { 4963 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); 4964 } 4965 #endif 4966 } 4967 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4968 for (e = eStart; e < eMax; ++e) { 4969 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4970 const PetscInt *cone, *support; 4971 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4972 4973 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4974 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4975 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4976 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4977 for (s = 0; s < size; ++s) { 4978 PetscInt r = 0; 4979 4980 if (support[s] < fMax) { 4981 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4982 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4983 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4984 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4985 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4986 faceSize += 2; 4987 } else { 4988 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4989 ++faceSize; 4990 } 4991 } 4992 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4993 for (s = 0; s < starSize*2; s += 2) { 4994 const PetscInt *cone, *ornt; 4995 PetscInt e01, e23; 4996 4997 if ((star[s] >= cStart) && (star[s] < cMax)) { 4998 /* Check edge 0-1 */ 4999 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 5000 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 5001 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 5002 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 5003 /* Check edge 2-3 */ 5004 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 5005 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 5006 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 5007 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 5008 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 5009 } 5010 } 5011 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 5012 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5013 #if defined(PETSC_USE_DEBUG) 5014 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5015 for (p = 0; p < 2+faceSize+cellSize; ++p) { 5016 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); 5017 } 5018 #endif 5019 } 5020 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5021 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5022 break; 5023 case REFINER_SIMPLEX_TO_HEX_3D: 5024 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5025 /* All cells have 6 faces */ 5026 for (c = cStart; c < cEnd; ++c) { 5027 const PetscInt newp = cStartNew + (c - cStart)*4; 5028 const PetscInt *cone, *ornt; 5029 PetscInt coneNew[6]; 5030 PetscInt orntNew[6]; 5031 5032 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5033 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5034 /* A hex */ 5035 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5036 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5037 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5038 orntNew[1] = -4; 5039 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5040 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5041 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5042 orntNew[3] = -1; 5043 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5044 orntNew[4] = 0; 5045 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5046 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5047 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5048 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5049 #if defined(PETSC_USE_DEBUG) 5050 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); 5051 for (p = 0; p < 6; ++p) { 5052 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); 5053 } 5054 #endif 5055 /* B hex */ 5056 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5057 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5058 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5059 orntNew[1] = 0; 5060 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5061 orntNew[2] = 0; 5062 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5063 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5064 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5065 orntNew[4] = 0; 5066 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5067 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5068 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5069 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5070 #if defined(PETSC_USE_DEBUG) 5071 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); 5072 for (p = 0; p < 6; ++p) { 5073 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); 5074 } 5075 #endif 5076 /* C hex */ 5077 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5078 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5079 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5080 orntNew[1] = -4; 5081 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5082 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5083 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5084 orntNew[3] = -1; 5085 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5086 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5087 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5088 orntNew[5] = -4; 5089 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5090 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5091 #if defined(PETSC_USE_DEBUG) 5092 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); 5093 for (p = 0; p < 6; ++p) { 5094 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); 5095 } 5096 #endif 5097 /* D hex */ 5098 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5099 orntNew[0] = 0; 5100 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5101 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5102 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5103 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5104 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5105 orntNew[3] = -1; 5106 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5107 orntNew[4] = 0; 5108 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5109 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5110 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5111 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5112 #if defined(PETSC_USE_DEBUG) 5113 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); 5114 for (p = 0; p < 6; ++p) { 5115 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); 5116 } 5117 #endif 5118 } 5119 /* Split faces have 4 edges and the same cells as the parent */ 5120 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5121 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5122 for (f = fStart; f < fEnd; ++f) { 5123 const PetscInt newp = fStartNew + (f - fStart)*3; 5124 const PetscInt *cone, *ornt, *support; 5125 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5126 5127 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5128 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5129 /* A quad */ 5130 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5131 orntNew[0] = ornt[2]; 5132 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5133 orntNew[1] = ornt[0]; 5134 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5135 orntNew[2] = 0; 5136 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5137 orntNew[3] = -2; 5138 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5139 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5140 #if defined(PETSC_USE_DEBUG) 5141 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); 5142 for (p = 0; p < 4; ++p) { 5143 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); 5144 } 5145 #endif 5146 /* B quad */ 5147 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5148 orntNew[0] = ornt[0]; 5149 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5150 orntNew[1] = ornt[1]; 5151 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5152 orntNew[2] = 0; 5153 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5154 orntNew[3] = -2; 5155 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5156 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5157 #if defined(PETSC_USE_DEBUG) 5158 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); 5159 for (p = 0; p < 4; ++p) { 5160 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); 5161 } 5162 #endif 5163 /* C quad */ 5164 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5165 orntNew[0] = ornt[1]; 5166 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5167 orntNew[1] = ornt[2]; 5168 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5169 orntNew[2] = 0; 5170 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5171 orntNew[3] = -2; 5172 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5173 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5174 #if defined(PETSC_USE_DEBUG) 5175 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); 5176 for (p = 0; p < 4; ++p) { 5177 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); 5178 } 5179 #endif 5180 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5181 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5182 for (r = 0; r < 3; ++r) { 5183 for (s = 0; s < supportSize; ++s) { 5184 PetscInt subf; 5185 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5186 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5187 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5188 for (c = 0; c < coneSize; ++c) { 5189 if (cone[c] == f) break; 5190 } 5191 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5192 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5193 } 5194 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5195 #if defined(PETSC_USE_DEBUG) 5196 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); 5197 for (p = 0; p < supportSize; ++p) { 5198 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); 5199 } 5200 #endif 5201 } 5202 } 5203 /* Interior faces have 4 edges and 2 cells */ 5204 for (c = cStart; c < cEnd; ++c) { 5205 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 5206 const PetscInt *cone, *ornt; 5207 PetscInt coneNew[4], orntNew[4]; 5208 PetscInt supportNew[2]; 5209 5210 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5211 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5212 /* Face {a, g, m, h} */ 5213 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5214 orntNew[0] = 0; 5215 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5216 orntNew[1] = 0; 5217 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5218 orntNew[2] = -2; 5219 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5220 orntNew[3] = -2; 5221 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5222 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5223 #if defined(PETSC_USE_DEBUG) 5224 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5225 for (p = 0; p < 4; ++p) { 5226 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); 5227 } 5228 #endif 5229 supportNew[0] = (c - cStart)*4 + 0; 5230 supportNew[1] = (c - cStart)*4 + 1; 5231 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5232 #if defined(PETSC_USE_DEBUG) 5233 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5234 for (p = 0; p < 2; ++p) { 5235 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); 5236 } 5237 #endif 5238 ++newp; 5239 /* Face {g, b, l , m} */ 5240 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5241 orntNew[0] = -2; 5242 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5243 orntNew[1] = 0; 5244 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5245 orntNew[2] = 0; 5246 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5247 orntNew[3] = -2; 5248 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5249 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5250 #if defined(PETSC_USE_DEBUG) 5251 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5252 for (p = 0; p < 4; ++p) { 5253 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); 5254 } 5255 #endif 5256 supportNew[0] = (c - cStart)*4 + 1; 5257 supportNew[1] = (c - cStart)*4 + 2; 5258 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5259 #if defined(PETSC_USE_DEBUG) 5260 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5261 for (p = 0; p < 2; ++p) { 5262 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); 5263 } 5264 #endif 5265 ++newp; 5266 /* Face {c, g, m, i} */ 5267 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5268 orntNew[0] = 0; 5269 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5270 orntNew[1] = 0; 5271 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5272 orntNew[2] = -2; 5273 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5274 orntNew[3] = -2; 5275 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5276 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5277 #if defined(PETSC_USE_DEBUG) 5278 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5279 for (p = 0; p < 4; ++p) { 5280 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); 5281 } 5282 #endif 5283 supportNew[0] = (c - cStart)*4 + 0; 5284 supportNew[1] = (c - cStart)*4 + 2; 5285 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5286 #if defined(PETSC_USE_DEBUG) 5287 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5288 for (p = 0; p < 2; ++p) { 5289 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); 5290 } 5291 #endif 5292 ++newp; 5293 /* Face {d, h, m, i} */ 5294 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5295 orntNew[0] = 0; 5296 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5297 orntNew[1] = 0; 5298 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5299 orntNew[2] = -2; 5300 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5301 orntNew[3] = -2; 5302 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5303 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5304 #if defined(PETSC_USE_DEBUG) 5305 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5306 for (p = 0; p < 4; ++p) { 5307 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); 5308 } 5309 #endif 5310 supportNew[0] = (c - cStart)*4 + 0; 5311 supportNew[1] = (c - cStart)*4 + 3; 5312 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5313 #if defined(PETSC_USE_DEBUG) 5314 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5315 for (p = 0; p < 2; ++p) { 5316 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); 5317 } 5318 #endif 5319 ++newp; 5320 /* Face {h, m, l, e} */ 5321 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5322 orntNew[0] = 0; 5323 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5324 orntNew[1] = -2; 5325 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5326 orntNew[2] = -2; 5327 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5328 orntNew[3] = 0; 5329 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5330 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5331 #if defined(PETSC_USE_DEBUG) 5332 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5333 for (p = 0; p < 4; ++p) { 5334 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); 5335 } 5336 #endif 5337 supportNew[0] = (c - cStart)*4 + 1; 5338 supportNew[1] = (c - cStart)*4 + 3; 5339 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5340 #if defined(PETSC_USE_DEBUG) 5341 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5342 for (p = 0; p < 2; ++p) { 5343 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); 5344 } 5345 #endif 5346 ++newp; 5347 /* Face {i, m, l, f} */ 5348 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5349 orntNew[0] = 0; 5350 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5351 orntNew[1] = -2; 5352 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5353 orntNew[2] = -2; 5354 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5355 orntNew[3] = 0; 5356 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5357 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5358 #if defined(PETSC_USE_DEBUG) 5359 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5360 for (p = 0; p < 4; ++p) { 5361 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); 5362 } 5363 #endif 5364 supportNew[0] = (c - cStart)*4 + 2; 5365 supportNew[1] = (c - cStart)*4 + 3; 5366 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5367 #if defined(PETSC_USE_DEBUG) 5368 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5369 for (p = 0; p < 2; ++p) { 5370 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); 5371 } 5372 #endif 5373 ++newp; 5374 } 5375 /* Split Edges have 2 vertices and the same faces as the parent */ 5376 for (e = eStart; e < eEnd; ++e) { 5377 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5378 5379 for (r = 0; r < 2; ++r) { 5380 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5381 const PetscInt *cone, *ornt, *support; 5382 PetscInt coneNew[2], coneSize, c, supportSize, s; 5383 5384 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5385 coneNew[0] = vStartNew + (cone[0] - vStart); 5386 coneNew[1] = vStartNew + (cone[1] - vStart); 5387 coneNew[(r+1)%2] = newv; 5388 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5389 #if defined(PETSC_USE_DEBUG) 5390 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5391 for (p = 0; p < 2; ++p) { 5392 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); 5393 } 5394 #endif 5395 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5396 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5397 for (s = 0; s < supportSize; ++s) { 5398 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5399 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5400 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5401 for (c = 0; c < coneSize; ++c) { 5402 if (cone[c] == e) break; 5403 } 5404 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 5405 } 5406 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5407 #if defined(PETSC_USE_DEBUG) 5408 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5409 for (p = 0; p < supportSize; ++p) { 5410 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); 5411 } 5412 #endif 5413 } 5414 } 5415 /* Face edges have 2 vertices and 2 + cell faces supports */ 5416 for (f = fStart; f < fEnd; ++f) { 5417 const PetscInt *cone, *ornt, *support; 5418 PetscInt coneSize, supportSize, s; 5419 5420 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5421 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5422 for (r = 0; r < 3; ++r) { 5423 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 5424 PetscInt coneNew[2]; 5425 PetscInt fint[4][3] = { {0, 1, 2}, 5426 {3, 4, 0}, 5427 {2, 5, 3}, 5428 {1, 4, 5} }; 5429 5430 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5431 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5432 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 5433 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5434 #if defined(PETSC_USE_DEBUG) 5435 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5436 for (p = 0; p < 2; ++p) { 5437 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); 5438 } 5439 #endif 5440 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 5441 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 5442 for (s = 0; s < supportSize; ++s) { 5443 PetscInt er; 5444 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5445 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5446 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5447 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 5448 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 5449 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 5450 } 5451 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5452 #if defined(PETSC_USE_DEBUG) 5453 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5454 for (p = 0; p < supportSize + 2; ++p) { 5455 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); 5456 } 5457 #endif 5458 } 5459 } 5460 /* Interior cell edges have 2 vertices and 3 faces */ 5461 for (c = cStart; c < cEnd; ++c) { 5462 const PetscInt *cone; 5463 PetscInt fint[4][3] = { {0,1,2}, 5464 {0,3,4}, 5465 {2,3,5}, 5466 {1,4,5} } ; 5467 5468 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5469 for (r = 0; r < 4; r++) { 5470 PetscInt coneNew[2], supportNew[3]; 5471 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 5472 5473 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5474 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 5475 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5476 #if defined(PETSC_USE_DEBUG) 5477 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5478 for (p = 0; p < 2; ++p) { 5479 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); 5480 } 5481 #endif 5482 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 5483 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 5484 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 5485 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5486 #if defined(PETSC_USE_DEBUG) 5487 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5488 for (p = 0; p < 3; ++p) { 5489 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); 5490 } 5491 #endif 5492 } 5493 } 5494 /* Old vertices have identical supports */ 5495 for (v = vStart; v < vEnd; ++v) { 5496 const PetscInt newp = vStartNew + (v - vStart); 5497 const PetscInt *support, *cone; 5498 PetscInt size, s; 5499 5500 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5501 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5502 for (s = 0; s < size; ++s) { 5503 PetscInt r = 0; 5504 5505 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5506 if (cone[1] == v) r = 1; 5507 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5508 } 5509 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5510 #if defined(PETSC_USE_DEBUG) 5511 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5512 for (p = 0; p < size; ++p) { 5513 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); 5514 } 5515 #endif 5516 } 5517 /* Edge vertices have 2 + faces supports */ 5518 for (e = eStart; e < eEnd; ++e) { 5519 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5520 const PetscInt *cone, *support; 5521 PetscInt size, s; 5522 5523 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5524 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5525 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5526 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5527 for (s = 0; s < size; ++s) { 5528 PetscInt r = 0, coneSize; 5529 5530 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5531 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5532 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 5533 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 5534 } 5535 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5536 #if defined(PETSC_USE_DEBUG) 5537 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5538 for (p = 0; p < 2+size; ++p) { 5539 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); 5540 } 5541 #endif 5542 } 5543 /* Face vertices have 3 + cells supports */ 5544 for (f = fStart; f < fEnd; ++f) { 5545 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5546 const PetscInt *cone, *support; 5547 PetscInt size, s; 5548 5549 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5550 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5551 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5552 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5553 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5554 for (s = 0; s < size; ++s) { 5555 PetscInt r = 0, coneSize; 5556 5557 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5558 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5559 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 5560 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 5561 } 5562 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5563 #if defined(PETSC_USE_DEBUG) 5564 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5565 for (p = 0; p < 3+size; ++p) { 5566 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); 5567 } 5568 #endif 5569 } 5570 /* Interior cell vertices have 4 supports */ 5571 for (c = cStart; c < cEnd; ++c) { 5572 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 5573 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5574 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5575 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5576 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5577 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5578 #if defined(PETSC_USE_DEBUG) 5579 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5580 for (p = 0; p < 4; ++p) { 5581 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); 5582 } 5583 #endif 5584 } 5585 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5586 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5587 break; 5588 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 5589 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 5590 cMax = PetscMin(cEnd, cMax); 5591 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5592 fMax = PetscMin(fEnd, fMax); 5593 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5594 eMax = PetscMin(eEnd, eMax); 5595 ierr = DMPlexGetRawFaces_Internal(dm, 3, 4, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5596 /* All cells have 6 faces */ 5597 for (c = cStart; c < cMax; ++c) { 5598 const PetscInt newp = cStartNew + (c - cStart)*4; 5599 const PetscInt *cone, *ornt; 5600 PetscInt coneNew[6]; 5601 PetscInt orntNew[6]; 5602 5603 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5604 #if defined(PETSC_USE_DEBUG) 5605 for (p = 0; p < 4; ++p) { 5606 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); 5607 } 5608 #endif 5609 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5610 /* A hex */ 5611 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5612 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5613 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5614 orntNew[1] = -4; 5615 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5616 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5617 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5618 orntNew[3] = -1; 5619 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5620 orntNew[4] = 0; 5621 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5622 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5623 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5624 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5625 #if defined(PETSC_USE_DEBUG) 5626 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); 5627 for (p = 0; p < 6; ++p) { 5628 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); 5629 } 5630 #endif 5631 /* B hex */ 5632 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5633 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5634 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5635 orntNew[1] = 0; 5636 coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5637 orntNew[2] = 0; 5638 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5639 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5640 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5641 orntNew[4] = 0; 5642 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5643 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5644 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5645 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5646 #if defined(PETSC_USE_DEBUG) 5647 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); 5648 for (p = 0; p < 6; ++p) { 5649 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); 5650 } 5651 #endif 5652 /* C hex */ 5653 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5654 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5655 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5656 orntNew[1] = -4; 5657 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5658 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5659 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5660 orntNew[3] = -1; 5661 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5662 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5663 coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5664 orntNew[5] = -4; 5665 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5666 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5667 #if defined(PETSC_USE_DEBUG) 5668 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); 5669 for (p = 0; p < 6; ++p) { 5670 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); 5671 } 5672 #endif 5673 /* D hex */ 5674 coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5675 orntNew[0] = 0; 5676 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5677 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5678 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5679 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5680 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5681 orntNew[3] = -1; 5682 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5683 orntNew[4] = 0; 5684 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5685 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5686 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5687 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5688 #if defined(PETSC_USE_DEBUG) 5689 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); 5690 for (p = 0; p < 6; ++p) { 5691 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); 5692 } 5693 #endif 5694 } 5695 for (c = cMax; c < cEnd; ++c) { 5696 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3; 5697 const PetscInt *cone, *ornt, *fornt; 5698 PetscInt coneNew[6], orntNew[6]; 5699 PetscInt o, of, cf; 5700 5701 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5702 #if defined(PETSC_USE_DEBUG) 5703 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); 5704 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); 5705 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); 5706 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); 5707 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); 5708 #endif 5709 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5710 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 5711 o = ornt[0] < 0 ? -1 : 1; 5712 /* A hex */ 5713 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5714 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5715 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */ 5716 orntNew[1] = ornt[1] < 0 ? 1 : -1; 5717 cf = GetTriEdge_Static(ornt[0], 2); 5718 of = fornt[cf] < 0 ? -1 : 1; 5719 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */ 5720 orntNew[2] = o*of < 0 ? 0 : -1; 5721 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */ 5722 orntNew[3] = -1; 5723 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */ 5724 orntNew[4] = 0; 5725 cf = GetTriEdge_Static(ornt[0], 0); 5726 of = fornt[cf] < 0 ? -1 : 1; 5727 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */ 5728 orntNew[5] = o*of < 0 ? 1 : -4; 5729 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5730 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5731 #if defined(PETSC_USE_DEBUG) 5732 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); 5733 for (p = 0; p < 6; ++p) { 5734 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); 5735 } 5736 #endif 5737 /* B hex */ 5738 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5739 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5740 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */ 5741 orntNew[1] = ornt[1] < 0 ? 2 : -4; 5742 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */ 5743 orntNew[2] = 0; 5744 cf = GetTriEdge_Static(ornt[0], 1); 5745 of = fornt[cf] < 0 ? -1 : 1; 5746 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */ 5747 orntNew[3] = o*of < 0 ? 0 : -1; 5748 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */ 5749 orntNew[4] = -1; 5750 cf = GetTriEdge_Static(ornt[0], 0); 5751 of = fornt[cf] < 0 ? -1 : 1; 5752 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */ 5753 orntNew[5] = o*of < 0 ? 1 : -4; 5754 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5755 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5756 #if defined(PETSC_USE_DEBUG) 5757 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); 5758 for (p = 0; p < 6; ++p) { 5759 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); 5760 } 5761 #endif 5762 /* C hex */ 5763 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5764 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5765 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */ 5766 orntNew[1] = ornt[1] < 0 ? 0 : -2; 5767 cf = GetTriEdge_Static(ornt[0], 2); 5768 of = fornt[cf] < 0 ? -1 : 1; 5769 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */ 5770 orntNew[2] = o*of < 0 ? 0 : -1; 5771 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */ 5772 orntNew[3] = 0; 5773 cf = GetTriEdge_Static(ornt[0], 1); 5774 of = fornt[cf] < 0 ? -1 : 1; 5775 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */ 5776 orntNew[4] = o*of < 0 ? 0 : -1; 5777 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */ 5778 orntNew[5] = -4; 5779 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5780 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5781 #if defined(PETSC_USE_DEBUG) 5782 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); 5783 for (p = 0; p < 6; ++p) { 5784 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); 5785 } 5786 #endif 5787 } 5788 5789 /* Split faces have 4 edges and the same cells as the parent */ 5790 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5791 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5792 for (f = fStart; f < fMax; ++f) { 5793 const PetscInt newp = fStartNew + (f - fStart)*3; 5794 const PetscInt *cone, *ornt, *support; 5795 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5796 5797 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5798 #if defined(PETSC_USE_DEBUG) 5799 for (p = 0; p < 3; ++p) { 5800 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); 5801 } 5802 #endif 5803 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5804 /* A quad */ 5805 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5806 orntNew[0] = ornt[2]; 5807 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5808 orntNew[1] = ornt[0]; 5809 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5810 orntNew[2] = 0; 5811 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5812 orntNew[3] = -2; 5813 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5814 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5815 #if defined(PETSC_USE_DEBUG) 5816 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); 5817 for (p = 0; p < 4; ++p) { 5818 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); 5819 } 5820 #endif 5821 /* B quad */ 5822 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5823 orntNew[0] = ornt[0]; 5824 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5825 orntNew[1] = ornt[1]; 5826 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5827 orntNew[2] = 0; 5828 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5829 orntNew[3] = -2; 5830 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5831 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5832 #if defined(PETSC_USE_DEBUG) 5833 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); 5834 for (p = 0; p < 4; ++p) { 5835 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); 5836 } 5837 #endif 5838 /* C quad */ 5839 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5840 orntNew[0] = ornt[1]; 5841 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5842 orntNew[1] = ornt[2]; 5843 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5844 orntNew[2] = 0; 5845 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5846 orntNew[3] = -2; 5847 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5848 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5849 #if defined(PETSC_USE_DEBUG) 5850 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); 5851 for (p = 0; p < 4; ++p) { 5852 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); 5853 } 5854 #endif 5855 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5856 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5857 for (r = 0; r < 3; ++r) { 5858 for (s = 0; s < supportSize; ++s) { 5859 PetscInt subf; 5860 5861 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5862 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); 5863 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); 5864 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5865 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5866 for (c = 0; c < coneSize; ++c) { 5867 if (cone[c] == f) break; 5868 } 5869 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5870 if (coneSize == 4) { 5871 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5872 } else if (coneSize == 5) { 5873 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); 5874 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf; 5875 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5876 } 5877 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5878 #if defined(PETSC_USE_DEBUG) 5879 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); 5880 for (p = 0; p < supportSize; ++p) { 5881 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); 5882 } 5883 #endif 5884 } 5885 } 5886 /* Interior faces have 4 edges and 2 cells */ 5887 for (c = cStart; c < cMax; ++c) { 5888 PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6; 5889 const PetscInt *cone, *ornt; 5890 PetscInt coneNew[4], orntNew[4]; 5891 PetscInt supportNew[2]; 5892 5893 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5894 #if defined(PETSC_USE_DEBUG) 5895 for (p = 0; p < 4; ++p) { 5896 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); 5897 } 5898 #endif 5899 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5900 /* Face {a, g, m, h} */ 5901 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5902 orntNew[0] = 0; 5903 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5904 orntNew[1] = 0; 5905 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5906 orntNew[2] = -2; 5907 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5908 orntNew[3] = -2; 5909 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5910 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5911 #if defined(PETSC_USE_DEBUG) 5912 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5913 for (p = 0; p < 4; ++p) { 5914 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); 5915 } 5916 #endif 5917 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5918 supportNew[1] = cStartNew + (c - cStart)*4 + 1; 5919 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5920 #if defined(PETSC_USE_DEBUG) 5921 for (p = 0; p < 2; ++p) { 5922 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); 5923 } 5924 #endif 5925 ++newp; 5926 /* Face {g, b, l , m} */ 5927 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5928 orntNew[0] = -2; 5929 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5930 orntNew[1] = 0; 5931 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5932 orntNew[2] = 0; 5933 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5934 orntNew[3] = -2; 5935 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5936 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5937 #if defined(PETSC_USE_DEBUG) 5938 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5939 for (p = 0; p < 4; ++p) { 5940 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); 5941 } 5942 #endif 5943 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5944 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5945 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5946 #if defined(PETSC_USE_DEBUG) 5947 for (p = 0; p < 2; ++p) { 5948 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); 5949 } 5950 #endif 5951 ++newp; 5952 /* Face {c, g, m, i} */ 5953 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5954 orntNew[0] = 0; 5955 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5956 orntNew[1] = 0; 5957 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5958 orntNew[2] = -2; 5959 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5960 orntNew[3] = -2; 5961 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5962 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5963 #if defined(PETSC_USE_DEBUG) 5964 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5965 for (p = 0; p < 4; ++p) { 5966 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); 5967 } 5968 #endif 5969 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5970 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5971 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5972 #if defined(PETSC_USE_DEBUG) 5973 for (p = 0; p < 2; ++p) { 5974 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); 5975 } 5976 #endif 5977 ++newp; 5978 /* Face {d, h, m, i} */ 5979 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5980 orntNew[0] = 0; 5981 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5982 orntNew[1] = 0; 5983 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5984 orntNew[2] = -2; 5985 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5986 orntNew[3] = -2; 5987 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5988 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5989 #if defined(PETSC_USE_DEBUG) 5990 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5991 for (p = 0; p < 4; ++p) { 5992 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); 5993 } 5994 #endif 5995 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5996 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 5997 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5998 #if defined(PETSC_USE_DEBUG) 5999 for (p = 0; p < 2; ++p) { 6000 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); 6001 } 6002 #endif 6003 ++newp; 6004 /* Face {h, m, l, e} */ 6005 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6006 orntNew[0] = 0; 6007 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6008 orntNew[1] = -2; 6009 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 6010 orntNew[2] = -2; 6011 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6012 orntNew[3] = 0; 6013 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6014 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6015 #if defined(PETSC_USE_DEBUG) 6016 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6017 for (p = 0; p < 4; ++p) { 6018 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); 6019 } 6020 #endif 6021 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 6022 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6023 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6024 #if defined(PETSC_USE_DEBUG) 6025 for (p = 0; p < 2; ++p) { 6026 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); 6027 } 6028 #endif 6029 ++newp; 6030 /* Face {i, m, l, f} */ 6031 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6032 orntNew[0] = 0; 6033 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6034 orntNew[1] = -2; 6035 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 6036 orntNew[2] = -2; 6037 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 6038 orntNew[3] = 0; 6039 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6040 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6041 #if defined(PETSC_USE_DEBUG) 6042 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6043 for (p = 0; p < 4; ++p) { 6044 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); 6045 } 6046 #endif 6047 supportNew[0] = cStartNew + (c - cStart)*4 + 2; 6048 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6049 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6050 #if defined(PETSC_USE_DEBUG) 6051 for (p = 0; p < 2; ++p) { 6052 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); 6053 } 6054 #endif 6055 ++newp; 6056 } 6057 /* Hybrid split faces have 4 edges and same cells */ 6058 for (f = fMax; f < fEnd; ++f) { 6059 const PetscInt *cone, *ornt, *support; 6060 PetscInt coneNew[4], orntNew[4]; 6061 PetscInt size, s; 6062 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2; 6063 6064 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6065 #if defined(PETSC_USE_DEBUG) 6066 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); 6067 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); 6068 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); 6069 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); 6070 #endif 6071 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6072 /* A face */ 6073 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 6074 orntNew[0] = ornt[0]; 6075 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 6076 orntNew[1] = 0; 6077 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 6078 orntNew[2] = ornt[1] < 0 ? 0 : -2; 6079 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax); 6080 orntNew[3] = ornt[2] < 0 ? 0 : -2; 6081 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6082 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6083 #if defined(PETSC_USE_DEBUG) 6084 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6085 for (p = 0; p < 4; ++p) { 6086 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); 6087 } 6088 #endif 6089 6090 /* B face */ 6091 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 6092 orntNew[0] = ornt[0]; 6093 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax); 6094 orntNew[1] = ornt[3]; 6095 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 6096 orntNew[2] = ornt[1] < 0 ? 0 : -2; 6097 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 6098 orntNew[3] = -2; 6099 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6100 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6101 #if defined(PETSC_USE_DEBUG) 6102 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); 6103 for (p = 0; p < 4; ++p) { 6104 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); 6105 } 6106 #endif 6107 6108 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6109 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6110 for (r = 0; r < 2; ++r) { 6111 for (s = 0; s < size; ++s) { 6112 const PetscInt *coneCell, *orntCell, *fornt; 6113 PetscInt coneSize, o, of, c; 6114 6115 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6116 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); 6117 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6118 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6119 o = orntCell[0] < 0 ? -1 : 1; 6120 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 6121 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); 6122 if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 6123 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 6124 of = fornt[c-2] < 0 ? -1 : 1; 6125 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 6126 } 6127 ierr = DMPlexSetSupport(rdm, newp + r, supportRef);CHKERRQ(ierr); 6128 #if defined(PETSC_USE_DEBUG) 6129 for (p = 0; p < size; ++p) { 6130 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); 6131 } 6132 #endif 6133 } 6134 } 6135 /* Interior hybrid faces have 4 edges and 2 cells */ 6136 for (c = cMax; c < cEnd; ++c) { 6137 PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3; 6138 const PetscInt *cone, *ornt; 6139 PetscInt coneNew[4], orntNew[4]; 6140 PetscInt supportNew[2]; 6141 6142 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6143 #if defined(PETSC_USE_DEBUG) 6144 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); 6145 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); 6146 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); 6147 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); 6148 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); 6149 #endif 6150 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6151 /* Face {a, g, h, d} */ 6152 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 6153 orntNew[0] = 0; 6154 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6155 orntNew[1] = 0; 6156 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 6157 orntNew[2] = -2; 6158 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax); 6159 orntNew[3] = -2; 6160 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6161 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6162 #if defined(PETSC_USE_DEBUG) 6163 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6164 for (p = 0; p < 4; ++p) { 6165 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); 6166 } 6167 #endif 6168 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6169 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6170 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6171 #if defined(PETSC_USE_DEBUG) 6172 for (p = 0; p < 2; ++p) { 6173 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); 6174 } 6175 #endif 6176 ++newp; 6177 /* Face {b, g, h, l} */ 6178 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 6179 orntNew[0] = 0; 6180 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6181 orntNew[1] = 0; 6182 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6183 orntNew[2] = -2; 6184 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax); 6185 orntNew[3] = -2; 6186 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6187 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6188 #if defined(PETSC_USE_DEBUG) 6189 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6190 for (p = 0; p < 4; ++p) { 6191 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); 6192 } 6193 #endif 6194 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6195 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6196 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6197 #if defined(PETSC_USE_DEBUG) 6198 for (p = 0; p < 2; ++p) { 6199 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); 6200 } 6201 #endif 6202 ++newp; 6203 /* Face {c, g, h, f} */ 6204 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 6205 orntNew[0] = 0; 6206 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6207 orntNew[1] = 0; 6208 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 6209 orntNew[2] = -2; 6210 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax); 6211 orntNew[3] = -2; 6212 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6213 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6214 #if defined(PETSC_USE_DEBUG) 6215 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6216 for (p = 0; p < 4; ++p) { 6217 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); 6218 } 6219 #endif 6220 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6221 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6222 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6223 #if defined(PETSC_USE_DEBUG) 6224 for (p = 0; p < 2; ++p) { 6225 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); 6226 } 6227 #endif 6228 } 6229 /* Face edges have 2 vertices and 2 + cell faces supports */ 6230 for (f = fStart; f < fMax; ++f) { 6231 const PetscInt *cone, *ornt, *support; 6232 PetscInt coneSize, supportSize, s; 6233 6234 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6235 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6236 for (r = 0; r < 3; ++r) { 6237 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 6238 PetscInt coneNew[2]; 6239 PetscInt fint[4][3] = { {0, 1, 2}, 6240 {3, 4, 0}, 6241 {2, 5, 3}, 6242 {1, 4, 5} }; 6243 6244 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6245 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); 6246 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6247 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 6248 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6249 #if defined(PETSC_USE_DEBUG) 6250 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6251 for (p = 0; p < 2; ++p) { 6252 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); 6253 } 6254 #endif 6255 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 6256 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 6257 for (s = 0; s < supportSize; ++s) { 6258 PetscInt er; 6259 6260 supportRef[2+s] = -1; 6261 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6262 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); 6263 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); 6264 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6265 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6266 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6267 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 6268 if (coneSize == 4) { 6269 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 6270 } else if (coneSize == 5) { 6271 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); 6272 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er; 6273 } 6274 } 6275 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6276 #if defined(PETSC_USE_DEBUG) 6277 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6278 for (p = 0; p < supportSize + 2; ++p) { 6279 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); 6280 } 6281 #endif 6282 } 6283 } 6284 /* Interior cell edges have 2 vertices and 3 faces */ 6285 for (c = cStart; c < cMax; ++c) { 6286 const PetscInt *cone; 6287 PetscInt fint[4][3] = { {0,1,2}, 6288 {0,3,4}, 6289 {2,3,5}, 6290 {1,4,5} } ; 6291 6292 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6293 for (r = 0; r < 4; r++) { 6294 PetscInt coneNew[2], supportNew[3]; 6295 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 6296 6297 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); 6298 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6299 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart; 6300 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6301 #if defined(PETSC_USE_DEBUG) 6302 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6303 for (p = 0; p < 2; ++p) { 6304 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); 6305 } 6306 #endif 6307 supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0]; 6308 supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1]; 6309 supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2]; 6310 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6311 #if defined(PETSC_USE_DEBUG) 6312 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6313 for (p = 0; p < 3; ++p) { 6314 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); 6315 } 6316 #endif 6317 } 6318 } 6319 /* Hybrid edges have two vertices and the same faces */ 6320 for (e = eMax; e < eEnd; ++e) { 6321 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 6322 const PetscInt *cone, *support, *fcone; 6323 PetscInt coneNew[2], size, fsize, s; 6324 6325 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6326 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6327 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6328 coneNew[0] = vStartNew + (cone[0] - vStart); 6329 coneNew[1] = vStartNew + (cone[1] - vStart); 6330 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6331 #if defined(PETSC_USE_DEBUG) 6332 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is a edge [%D, %D)", newp, eStartNew, eEndNew); 6333 for (p = 0; p < 2; ++p) { 6334 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); 6335 } 6336 #endif 6337 for (s = 0; s < size; ++s) { 6338 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6339 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6340 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6341 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 6342 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2; 6343 } 6344 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6345 #if defined(PETSC_USE_DEBUG) 6346 for (p = 0; p < size; ++p) { 6347 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); 6348 } 6349 #endif 6350 } 6351 /* Hybrid face edges have 2 vertices and 2 + cell faces supports */ 6352 for (f = fMax; f < fEnd; ++f) { 6353 const PetscInt *cone, *ornt, *support; 6354 PetscInt coneSize, supportSize; 6355 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax; 6356 PetscInt coneNew[2], s; 6357 6358 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6359 #if defined(PETSC_USE_DEBUG) 6360 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); 6361 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); 6362 #endif 6363 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6364 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6365 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6366 #if defined(PETSC_USE_DEBUG) 6367 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6368 for (p = 0; p < 2; ++p) { 6369 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); 6370 } 6371 #endif 6372 supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0; 6373 supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1; 6374 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6375 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6376 for (s = 0; s < supportSize; ++s) { 6377 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6378 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); 6379 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6380 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6381 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6382 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); 6383 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2; 6384 } 6385 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6386 #if defined(PETSC_USE_DEBUG) 6387 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6388 for (p = 0; p < supportSize + 2; ++p) { 6389 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); 6390 } 6391 #endif 6392 } 6393 /* Hybrid cell edges have 2 vertices and 3 faces */ 6394 for (c = cMax; c < cEnd; ++c) { 6395 PetscInt coneNew[2], supportNew[3]; 6396 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6397 const PetscInt *cone; 6398 6399 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6400 #if defined(PETSC_USE_DEBUG) 6401 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); 6402 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); 6403 #endif 6404 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6405 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6406 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6407 #if defined(PETSC_USE_DEBUG) 6408 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6409 for (p = 0; p < 2; ++p) { 6410 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); 6411 } 6412 #endif 6413 supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 6414 supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 6415 supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 6416 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6417 #if defined(PETSC_USE_DEBUG) 6418 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6419 for (p = 0; p < 3; ++p) { 6420 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); 6421 } 6422 #endif 6423 } 6424 /* Old vertices have identical supports */ 6425 for (v = vStart; v < vEnd; ++v) { 6426 const PetscInt newp = vStartNew + (v - vStart); 6427 const PetscInt *support, *cone; 6428 PetscInt size, s; 6429 6430 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6431 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6432 for (s = 0; s < size; ++s) { 6433 const PetscInt e = support[s]; 6434 6435 supportRef[s] = -1; 6436 if (eStart <= e) { 6437 if (e < eMax) { 6438 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6439 supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0); 6440 } else if (e < eEnd) { 6441 supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax; 6442 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6443 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6444 } 6445 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6446 #if defined(PETSC_USE_DEBUG) 6447 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6448 for (p = 0; p < size; ++p) { 6449 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); 6450 } 6451 #endif 6452 } 6453 /* Interior edge vertices have 2 + faces supports */ 6454 for (e = eStart; e < eMax; ++e) { 6455 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6456 const PetscInt *cone, *support; 6457 PetscInt size, s; 6458 6459 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6460 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6461 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6462 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6463 for (s = 0; s < size; ++s) { 6464 PetscInt r, coneSize; 6465 6466 supportRef[2+s] = -1; 6467 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6468 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); 6469 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); 6470 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6471 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 6472 if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r; 6473 else if (coneSize == 4) { 6474 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); 6475 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax; 6476 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6477 } 6478 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6479 #if defined(PETSC_USE_DEBUG) 6480 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6481 for (p = 0; p < 2+size; ++p) { 6482 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); 6483 } 6484 #endif 6485 } 6486 /* Split Edges have 2 vertices and the same faces as the parent */ 6487 for (e = eStart; e < eMax; ++e) { 6488 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6489 6490 for (r = 0; r < 2; ++r) { 6491 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6492 const PetscInt *cone, *ornt, *support; 6493 PetscInt coneNew[2], coneSize, c, supportSize, s; 6494 6495 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6496 coneNew[0] = vStartNew + (cone[0] - vStart); 6497 coneNew[1] = vStartNew + (cone[1] - vStart); 6498 coneNew[(r+1)%2] = newv; 6499 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6500 #if defined(PETSC_USE_DEBUG) 6501 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6502 for (p = 0; p < 2; ++p) { 6503 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); 6504 } 6505 #endif 6506 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6507 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6508 for (s = 0; s < supportSize; ++s) { 6509 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6510 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); 6511 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); 6512 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6513 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6514 for (c = 0; c < coneSize; ++c) { 6515 if (cone[c] == e) break; 6516 } 6517 if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 6518 else if (coneSize == 4) { 6519 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); 6520 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6521 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6522 } 6523 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6524 #if defined(PETSC_USE_DEBUG) 6525 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6526 for (p = 0; p < supportSize; ++p) { 6527 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); 6528 } 6529 #endif 6530 } 6531 } 6532 /* Face vertices have 3 + cells supports */ 6533 for (f = fStart; f < fMax; ++f) { 6534 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6535 const PetscInt *cone, *support; 6536 PetscInt size, s; 6537 6538 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6539 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6540 supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 6541 supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 6542 supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 6543 for (s = 0; s < size; ++s) { 6544 PetscInt r, coneSize; 6545 6546 supportRef[3+s] = -1; 6547 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6548 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); 6549 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); 6550 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6551 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 6552 if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r; 6553 else if (coneSize == 5) { 6554 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); 6555 supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax; 6556 } 6557 } 6558 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6559 #if defined(PETSC_USE_DEBUG) 6560 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6561 for (p = 0; p < 3+size; ++p) { 6562 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); 6563 } 6564 #endif 6565 } 6566 /* Interior cell vertices have 4 supports */ 6567 for (c = cStart; c < cMax; ++c) { 6568 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 6569 6570 supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 6571 supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6572 supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6573 supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6574 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6575 #if defined(PETSC_USE_DEBUG) 6576 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6577 for (p = 0; p < 4; ++p) { 6578 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); 6579 } 6580 #endif 6581 } 6582 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6583 ierr = DMPlexRestoreFaces_Internal(dm, 3, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 6584 break; 6585 case REFINER_HEX_3D: 6586 /* 6587 Bottom (viewed from top) Top 6588 1---------2---------2 7---------2---------6 6589 | | | | | | 6590 | B 2 C | | H 2 G | 6591 | | | | | | 6592 3----3----0----1----1 3----3----0----1----1 6593 | | | | | | 6594 | A 0 D | | E 0 F | 6595 | | | | | | 6596 0---------0---------3 4---------0---------5 6597 */ 6598 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 6599 for (c = cStart; c < cEnd; ++c) { 6600 const PetscInt newp = (c - cStart)*8; 6601 const PetscInt *cone, *ornt; 6602 PetscInt coneNew[6], orntNew[6]; 6603 6604 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6605 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6606 /* A hex */ 6607 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 6608 orntNew[0] = ornt[0]; 6609 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6610 orntNew[1] = 0; 6611 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 6612 orntNew[2] = ornt[2]; 6613 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6614 orntNew[3] = 0; 6615 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6616 orntNew[4] = 0; 6617 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 6618 orntNew[5] = ornt[5]; 6619 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 6620 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 6621 #if defined(PETSC_USE_DEBUG) 6622 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); 6623 for (p = 0; p < 6; ++p) { 6624 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6625 } 6626 #endif 6627 /* B hex */ 6628 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 6629 orntNew[0] = ornt[0]; 6630 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6631 orntNew[1] = 0; 6632 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6633 orntNew[2] = -1; 6634 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 6635 orntNew[3] = ornt[3]; 6636 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6637 orntNew[4] = 0; 6638 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 6639 orntNew[5] = ornt[5]; 6640 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6641 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6642 #if defined(PETSC_USE_DEBUG) 6643 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); 6644 for (p = 0; p < 6; ++p) { 6645 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 6646 } 6647 #endif 6648 /* C hex */ 6649 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 6650 orntNew[0] = ornt[0]; 6651 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6652 orntNew[1] = 0; 6653 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6654 orntNew[2] = -1; 6655 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 6656 orntNew[3] = ornt[3]; 6657 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 6658 orntNew[4] = ornt[4]; 6659 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6660 orntNew[5] = -4; 6661 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 6662 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 6663 #if defined(PETSC_USE_DEBUG) 6664 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); 6665 for (p = 0; p < 6; ++p) { 6666 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); 6667 } 6668 #endif 6669 /* D hex */ 6670 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 6671 orntNew[0] = ornt[0]; 6672 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6673 orntNew[1] = 0; 6674 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 6675 orntNew[2] = ornt[2]; 6676 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6677 orntNew[3] = 0; 6678 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 6679 orntNew[4] = ornt[4]; 6680 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6681 orntNew[5] = -4; 6682 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 6683 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 6684 #if defined(PETSC_USE_DEBUG) 6685 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); 6686 for (p = 0; p < 6; ++p) { 6687 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); 6688 } 6689 #endif 6690 /* E hex */ 6691 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6692 orntNew[0] = -4; 6693 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 6694 orntNew[1] = ornt[1]; 6695 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 6696 orntNew[2] = ornt[2]; 6697 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6698 orntNew[3] = 0; 6699 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6700 orntNew[4] = -1; 6701 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 6702 orntNew[5] = ornt[5]; 6703 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 6704 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 6705 #if defined(PETSC_USE_DEBUG) 6706 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); 6707 for (p = 0; p < 6; ++p) { 6708 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); 6709 } 6710 #endif 6711 /* F hex */ 6712 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6713 orntNew[0] = -4; 6714 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 6715 orntNew[1] = ornt[1]; 6716 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 6717 orntNew[2] = ornt[2]; 6718 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6719 orntNew[3] = -1; 6720 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 6721 orntNew[4] = ornt[4]; 6722 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6723 orntNew[5] = 1; 6724 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 6725 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 6726 #if defined(PETSC_USE_DEBUG) 6727 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); 6728 for (p = 0; p < 6; ++p) { 6729 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); 6730 } 6731 #endif 6732 /* G hex */ 6733 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6734 orntNew[0] = -4; 6735 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 6736 orntNew[1] = ornt[1]; 6737 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6738 orntNew[2] = 0; 6739 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 6740 orntNew[3] = ornt[3]; 6741 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 6742 orntNew[4] = ornt[4]; 6743 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6744 orntNew[5] = -3; 6745 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 6746 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 6747 #if defined(PETSC_USE_DEBUG) 6748 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); 6749 for (p = 0; p < 6; ++p) { 6750 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); 6751 } 6752 #endif 6753 /* H hex */ 6754 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6755 orntNew[0] = -4; 6756 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 6757 orntNew[1] = ornt[1]; 6758 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6759 orntNew[2] = -1; 6760 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 6761 orntNew[3] = ornt[3]; 6762 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6763 orntNew[4] = 3; 6764 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 6765 orntNew[5] = ornt[5]; 6766 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 6767 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 6768 #if defined(PETSC_USE_DEBUG) 6769 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); 6770 for (p = 0; p < 6; ++p) { 6771 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); 6772 } 6773 #endif 6774 } 6775 /* Split faces have 4 edges and the same cells as the parent */ 6776 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6777 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 6778 for (f = fStart; f < fEnd; ++f) { 6779 for (r = 0; r < 4; ++r) { 6780 /* TODO: This can come from GetFaces_Internal() */ 6781 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}; 6782 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 6783 const PetscInt *cone, *ornt, *support; 6784 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 6785 6786 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6787 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6788 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 6789 orntNew[(r+3)%4] = ornt[(r+3)%4]; 6790 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 6791 orntNew[(r+0)%4] = ornt[r]; 6792 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6793 orntNew[(r+1)%4] = 0; 6794 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 6795 orntNew[(r+2)%4] = -2; 6796 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6797 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6798 #if defined(PETSC_USE_DEBUG) 6799 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6800 for (p = 0; p < 4; ++p) { 6801 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); 6802 } 6803 #endif 6804 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6805 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6806 for (s = 0; s < supportSize; ++s) { 6807 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6808 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6809 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6810 for (c = 0; c < coneSize; ++c) { 6811 if (cone[c] == f) break; 6812 } 6813 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 6814 } 6815 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6816 #if defined(PETSC_USE_DEBUG) 6817 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6818 for (p = 0; p < supportSize; ++p) { 6819 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); 6820 } 6821 #endif 6822 } 6823 } 6824 /* Interior faces have 4 edges and 2 cells */ 6825 for (c = cStart; c < cEnd; ++c) { 6826 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}; 6827 const PetscInt *cone, *ornt; 6828 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 6829 6830 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6831 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6832 /* A-D face */ 6833 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 6834 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 6835 orntNew[0] = 0; 6836 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6837 orntNew[1] = 0; 6838 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6839 orntNew[2] = -2; 6840 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 6841 orntNew[3] = -2; 6842 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6843 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6844 #if defined(PETSC_USE_DEBUG) 6845 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6846 for (p = 0; p < 4; ++p) { 6847 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6848 } 6849 #endif 6850 /* C-D face */ 6851 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 6852 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 6853 orntNew[0] = 0; 6854 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6855 orntNew[1] = 0; 6856 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6857 orntNew[2] = -2; 6858 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 6859 orntNew[3] = -2; 6860 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6861 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6862 #if defined(PETSC_USE_DEBUG) 6863 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6864 for (p = 0; p < 4; ++p) { 6865 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6866 } 6867 #endif 6868 /* B-C face */ 6869 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 6870 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 6871 orntNew[0] = -2; 6872 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 6873 orntNew[1] = 0; 6874 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6875 orntNew[2] = 0; 6876 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6877 orntNew[3] = -2; 6878 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6879 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6880 #if defined(PETSC_USE_DEBUG) 6881 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6882 for (p = 0; p < 4; ++p) { 6883 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6884 } 6885 #endif 6886 /* A-B face */ 6887 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 6888 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 6889 orntNew[0] = -2; 6890 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 6891 orntNew[1] = 0; 6892 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6893 orntNew[2] = 0; 6894 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6895 orntNew[3] = -2; 6896 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6897 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6898 #if defined(PETSC_USE_DEBUG) 6899 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6900 for (p = 0; p < 4; ++p) { 6901 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6902 } 6903 #endif 6904 /* E-F face */ 6905 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 6906 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6907 orntNew[0] = -2; 6908 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 6909 orntNew[1] = -2; 6910 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 6911 orntNew[2] = 0; 6912 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6913 orntNew[3] = 0; 6914 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6915 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6916 #if defined(PETSC_USE_DEBUG) 6917 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6918 for (p = 0; p < 4; ++p) { 6919 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 6920 } 6921 #endif 6922 /* F-G face */ 6923 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 6924 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6925 orntNew[0] = -2; 6926 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 6927 orntNew[1] = -2; 6928 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 6929 orntNew[2] = 0; 6930 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6931 orntNew[3] = 0; 6932 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6933 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6934 #if defined(PETSC_USE_DEBUG) 6935 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6936 for (p = 0; p < 4; ++p) { 6937 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); 6938 } 6939 #endif 6940 /* G-H face */ 6941 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 6942 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 6943 orntNew[0] = -2; 6944 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 6945 orntNew[1] = 0; 6946 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6947 orntNew[2] = 0; 6948 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6949 orntNew[3] = -2; 6950 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6951 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6952 #if defined(PETSC_USE_DEBUG) 6953 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6954 for (p = 0; p < 4; ++p) { 6955 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); 6956 } 6957 #endif 6958 /* E-H face */ 6959 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 6960 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6961 orntNew[0] = -2; 6962 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 6963 orntNew[1] = -2; 6964 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 6965 orntNew[2] = 0; 6966 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6967 orntNew[3] = 0; 6968 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6969 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6970 #if defined(PETSC_USE_DEBUG) 6971 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6972 for (p = 0; p < 4; ++p) { 6973 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); 6974 } 6975 #endif 6976 /* A-E face */ 6977 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 6978 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 6979 orntNew[0] = 0; 6980 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6981 orntNew[1] = 0; 6982 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6983 orntNew[2] = -2; 6984 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 6985 orntNew[3] = -2; 6986 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6987 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6988 #if defined(PETSC_USE_DEBUG) 6989 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6990 for (p = 0; p < 4; ++p) { 6991 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); 6992 } 6993 #endif 6994 /* D-F face */ 6995 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 6996 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 6997 orntNew[0] = -2; 6998 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 6999 orntNew[1] = 0; 7000 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 7001 orntNew[2] = 0; 7002 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 7003 orntNew[3] = -2; 7004 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7005 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7006 #if defined(PETSC_USE_DEBUG) 7007 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7008 for (p = 0; p < 4; ++p) { 7009 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); 7010 } 7011 #endif 7012 /* C-G face */ 7013 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 7014 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 7015 orntNew[0] = -2; 7016 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7017 orntNew[1] = -2; 7018 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7019 orntNew[2] = 0; 7020 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 7021 orntNew[3] = 0; 7022 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7023 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7024 #if defined(PETSC_USE_DEBUG) 7025 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7026 for (p = 0; p < 4; ++p) { 7027 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); 7028 } 7029 #endif 7030 /* B-H face */ 7031 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 7032 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 7033 orntNew[0] = 0; 7034 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 7035 orntNew[1] = -2; 7036 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7037 orntNew[2] = -2; 7038 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7039 orntNew[3] = 0; 7040 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7041 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7042 #if defined(PETSC_USE_DEBUG) 7043 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7044 for (p = 0; p < 4; ++p) { 7045 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); 7046 } 7047 #endif 7048 for (r = 0; r < 12; ++r) { 7049 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 7050 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7051 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7052 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7053 #if defined(PETSC_USE_DEBUG) 7054 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7055 for (p = 0; p < 2; ++p) { 7056 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); 7057 } 7058 #endif 7059 } 7060 } 7061 /* Split edges have 2 vertices and the same faces as the parent */ 7062 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7063 for (e = eStart; e < eEnd; ++e) { 7064 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7065 7066 for (r = 0; r < 2; ++r) { 7067 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7068 const PetscInt *cone, *ornt, *support; 7069 PetscInt coneNew[2], coneSize, c, supportSize, s; 7070 7071 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7072 coneNew[0] = vStartNew + (cone[0] - vStart); 7073 coneNew[1] = vStartNew + (cone[1] - vStart); 7074 coneNew[(r+1)%2] = newv; 7075 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7076 #if defined(PETSC_USE_DEBUG) 7077 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7078 for (p = 0; p < 2; ++p) { 7079 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); 7080 } 7081 #endif 7082 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7083 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7084 for (s = 0; s < supportSize; ++s) { 7085 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7086 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7087 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7088 for (c = 0; c < coneSize; ++c) { 7089 if (cone[c] == e) break; 7090 } 7091 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 7092 } 7093 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7094 #if defined(PETSC_USE_DEBUG) 7095 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7096 for (p = 0; p < supportSize; ++p) { 7097 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); 7098 } 7099 #endif 7100 } 7101 } 7102 /* Face edges have 2 vertices and 2+cells faces */ 7103 for (f = fStart; f < fEnd; ++f) { 7104 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}; 7105 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7106 const PetscInt *cone, *coneCell, *orntCell, *support; 7107 PetscInt coneNew[2], coneSize, c, supportSize, s; 7108 7109 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7110 for (r = 0; r < 4; ++r) { 7111 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7112 7113 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7114 coneNew[1] = newv; 7115 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7116 #if defined(PETSC_USE_DEBUG) 7117 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7118 for (p = 0; p < 2; ++p) { 7119 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); 7120 } 7121 #endif 7122 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7123 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7124 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7125 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7126 for (s = 0; s < supportSize; ++s) { 7127 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7128 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7129 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7130 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7131 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7132 } 7133 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7134 #if defined(PETSC_USE_DEBUG) 7135 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7136 for (p = 0; p < 2+supportSize; ++p) { 7137 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); 7138 } 7139 #endif 7140 } 7141 } 7142 /* Cell edges have 2 vertices and 4 faces */ 7143 for (c = cStart; c < cEnd; ++c) { 7144 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}; 7145 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7146 const PetscInt *cone; 7147 PetscInt coneNew[2], supportNew[4]; 7148 7149 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7150 for (r = 0; r < 6; ++r) { 7151 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7152 7153 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 7154 coneNew[1] = newv; 7155 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7156 #if defined(PETSC_USE_DEBUG) 7157 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7158 for (p = 0; p < 2; ++p) { 7159 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); 7160 } 7161 #endif 7162 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7163 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7164 #if defined(PETSC_USE_DEBUG) 7165 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7166 for (p = 0; p < 4; ++p) { 7167 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); 7168 } 7169 #endif 7170 } 7171 } 7172 /* Old vertices have identical supports */ 7173 for (v = vStart; v < vEnd; ++v) { 7174 const PetscInt newp = vStartNew + (v - vStart); 7175 const PetscInt *support, *cone; 7176 PetscInt size, s; 7177 7178 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 7179 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 7180 for (s = 0; s < size; ++s) { 7181 PetscInt r = 0; 7182 7183 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7184 if (cone[1] == v) r = 1; 7185 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 7186 } 7187 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7188 #if defined(PETSC_USE_DEBUG) 7189 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7190 for (p = 0; p < size; ++p) { 7191 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); 7192 } 7193 #endif 7194 } 7195 /* Edge vertices have 2 + faces supports */ 7196 for (e = eStart; e < eEnd; ++e) { 7197 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 7198 const PetscInt *cone, *support; 7199 PetscInt size, s; 7200 7201 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7202 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7203 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 7204 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 7205 for (s = 0; s < size; ++s) { 7206 PetscInt r; 7207 7208 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7209 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 7210 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 7211 } 7212 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7213 #if defined(PETSC_USE_DEBUG) 7214 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7215 for (p = 0; p < 2+size; ++p) { 7216 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); 7217 } 7218 #endif 7219 } 7220 /* Face vertices have 4 + cells supports */ 7221 for (f = fStart; f < fEnd; ++f) { 7222 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7223 const PetscInt *cone, *support; 7224 PetscInt size, s; 7225 7226 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7227 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7228 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7229 for (s = 0; s < size; ++s) { 7230 PetscInt r; 7231 7232 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7233 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 7234 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 7235 } 7236 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7237 #if defined(PETSC_USE_DEBUG) 7238 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7239 for (p = 0; p < 4+size; ++p) { 7240 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); 7241 } 7242 #endif 7243 } 7244 /* Cell vertices have 6 supports */ 7245 for (c = cStart; c < cEnd; ++c) { 7246 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7247 PetscInt supportNew[6]; 7248 7249 for (r = 0; r < 6; ++r) { 7250 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7251 } 7252 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7253 } 7254 ierr = PetscFree(supportRef);CHKERRQ(ierr); 7255 break; 7256 case REFINER_HYBRID_HEX_3D: 7257 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 7258 /* 7259 Bottom (viewed from top) Top 7260 1---------2---------2 7---------2---------6 7261 | | | | | | 7262 | B 2 C | | H 2 G | 7263 | | | | | | 7264 3----3----0----1----1 3----3----0----1----1 7265 | | | | | | 7266 | A 0 D | | E 0 F | 7267 | | | | | | 7268 0---------0---------3 4---------0---------5 7269 */ 7270 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 7271 for (c = cStart; c < cMax; ++c) { 7272 const PetscInt newp = (c - cStart)*8; 7273 const PetscInt *cone, *ornt; 7274 PetscInt coneNew[6], orntNew[6]; 7275 7276 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7277 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7278 /* A hex */ 7279 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 7280 orntNew[0] = ornt[0]; 7281 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7282 orntNew[1] = 0; 7283 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 7284 orntNew[2] = ornt[2]; 7285 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7286 orntNew[3] = 0; 7287 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7288 orntNew[4] = 0; 7289 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 7290 orntNew[5] = ornt[5]; 7291 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 7292 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 7293 #if defined(PETSC_USE_DEBUG) 7294 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); 7295 for (p = 0; p < 6; ++p) { 7296 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7297 } 7298 #endif 7299 /* B hex */ 7300 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 7301 orntNew[0] = ornt[0]; 7302 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7303 orntNew[1] = 0; 7304 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7305 orntNew[2] = -1; 7306 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 7307 orntNew[3] = ornt[3]; 7308 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7309 orntNew[4] = 0; 7310 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 7311 orntNew[5] = ornt[5]; 7312 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 7313 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 7314 #if defined(PETSC_USE_DEBUG) 7315 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); 7316 for (p = 0; p < 6; ++p) { 7317 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fMaxNew); 7318 } 7319 #endif 7320 /* C hex */ 7321 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 7322 orntNew[0] = ornt[0]; 7323 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7324 orntNew[1] = 0; 7325 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7326 orntNew[2] = -1; 7327 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 7328 orntNew[3] = ornt[3]; 7329 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 7330 orntNew[4] = ornt[4]; 7331 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7332 orntNew[5] = -4; 7333 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 7334 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 7335 #if defined(PETSC_USE_DEBUG) 7336 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); 7337 for (p = 0; p < 6; ++p) { 7338 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); 7339 } 7340 #endif 7341 /* D hex */ 7342 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 7343 orntNew[0] = ornt[0]; 7344 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7345 orntNew[1] = 0; 7346 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 7347 orntNew[2] = ornt[2]; 7348 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7349 orntNew[3] = 0; 7350 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 7351 orntNew[4] = ornt[4]; 7352 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7353 orntNew[5] = -4; 7354 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 7355 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 7356 #if defined(PETSC_USE_DEBUG) 7357 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); 7358 for (p = 0; p < 6; ++p) { 7359 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); 7360 } 7361 #endif 7362 /* E hex */ 7363 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7364 orntNew[0] = -4; 7365 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 7366 orntNew[1] = ornt[1]; 7367 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 7368 orntNew[2] = ornt[2]; 7369 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7370 orntNew[3] = 0; 7371 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7372 orntNew[4] = -1; 7373 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 7374 orntNew[5] = ornt[5]; 7375 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 7376 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 7377 #if defined(PETSC_USE_DEBUG) 7378 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); 7379 for (p = 0; p < 6; ++p) { 7380 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); 7381 } 7382 #endif 7383 /* F hex */ 7384 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7385 orntNew[0] = -4; 7386 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 7387 orntNew[1] = ornt[1]; 7388 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 7389 orntNew[2] = ornt[2]; 7390 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7391 orntNew[3] = -1; 7392 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 7393 orntNew[4] = ornt[4]; 7394 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7395 orntNew[5] = 1; 7396 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 7397 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 7398 #if defined(PETSC_USE_DEBUG) 7399 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); 7400 for (p = 0; p < 6; ++p) { 7401 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); 7402 } 7403 #endif 7404 /* G hex */ 7405 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7406 orntNew[0] = -4; 7407 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 7408 orntNew[1] = ornt[1]; 7409 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7410 orntNew[2] = 0; 7411 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 7412 orntNew[3] = ornt[3]; 7413 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 7414 orntNew[4] = ornt[4]; 7415 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7416 orntNew[5] = -3; 7417 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 7418 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 7419 #if defined(PETSC_USE_DEBUG) 7420 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); 7421 for (p = 0; p < 6; ++p) { 7422 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); 7423 } 7424 #endif 7425 /* H hex */ 7426 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7427 orntNew[0] = -4; 7428 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 7429 orntNew[1] = ornt[1]; 7430 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7431 orntNew[2] = -1; 7432 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 7433 orntNew[3] = ornt[3]; 7434 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7435 orntNew[4] = 3; 7436 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 7437 orntNew[5] = ornt[5]; 7438 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 7439 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 7440 #if defined(PETSC_USE_DEBUG) 7441 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); 7442 for (p = 0; p < 6; ++p) { 7443 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); 7444 } 7445 #endif 7446 } 7447 /* Hybrid cells have 6 faces: Front, Back, Sides */ 7448 /* 7449 3---------2---------2 7450 | | | 7451 | D 2 C | 7452 | | | 7453 3----3----0----1----1 7454 | | | 7455 | A 0 B | 7456 | | | 7457 0---------0---------1 7458 */ 7459 for (c = cMax; c < cEnd; ++c) { 7460 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 7461 const PetscInt *cone, *ornt, *fornt; 7462 PetscInt coneNew[6], orntNew[6], o, of, i; 7463 7464 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7465 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7466 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 7467 o = ornt[0] < 0 ? -1 : 1; 7468 for (r = 0; r < 4; ++r) { 7469 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 7470 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 7471 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 7472 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]); 7473 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 7474 orntNew[0] = ornt[0]; 7475 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 7476 orntNew[1] = ornt[0]; 7477 of = fornt[edgeA] < 0 ? -1 : 1; 7478 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 7479 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 7480 orntNew[i] = ornt[edgeA]; 7481 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 7482 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 7483 orntNew[i] = 0; 7484 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 7485 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 7486 orntNew[i] = -2; 7487 of = fornt[edgeB] < 0 ? -1 : 1; 7488 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 7489 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 7490 orntNew[i] = ornt[edgeB]; 7491 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7492 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7493 #if defined(PETSC_USE_DEBUG) 7494 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); 7495 for (p = 0; p < 2; ++p) { 7496 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); 7497 } 7498 for (p = 2; p < 6; ++p) { 7499 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); 7500 } 7501 #endif 7502 } 7503 } 7504 /* Interior split faces have 4 edges and the same cells as the parent */ 7505 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7506 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 7507 for (f = fStart; f < fMax; ++f) { 7508 for (r = 0; r < 4; ++r) { 7509 /* TODO: This can come from GetFaces_Internal() */ 7510 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}; 7511 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 7512 const PetscInt *cone, *ornt, *support; 7513 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 7514 7515 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7516 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7517 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 7518 orntNew[(r+3)%4] = ornt[(r+3)%4]; 7519 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 7520 orntNew[(r+0)%4] = ornt[r]; 7521 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7522 orntNew[(r+1)%4] = 0; 7523 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 7524 orntNew[(r+2)%4] = -2; 7525 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7526 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7527 #if defined(PETSC_USE_DEBUG) 7528 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7529 for (p = 0; p < 4; ++p) { 7530 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); 7531 } 7532 #endif 7533 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7534 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7535 for (s = 0; s < supportSize; ++s) { 7536 PetscInt subf; 7537 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7538 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7539 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7540 for (c = 0; c < coneSize; ++c) { 7541 if (cone[c] == f) break; 7542 } 7543 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 7544 if (support[s] < cMax) { 7545 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 7546 } else { 7547 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 7548 } 7549 } 7550 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7551 #if defined(PETSC_USE_DEBUG) 7552 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7553 for (p = 0; p < supportSize; ++p) { 7554 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); 7555 } 7556 #endif 7557 } 7558 } 7559 /* Interior cell faces have 4 edges and 2 cells */ 7560 for (c = cStart; c < cMax; ++c) { 7561 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}; 7562 const PetscInt *cone, *ornt; 7563 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 7564 7565 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7566 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7567 /* A-D face */ 7568 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 7569 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 7570 orntNew[0] = 0; 7571 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7572 orntNew[1] = 0; 7573 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7574 orntNew[2] = -2; 7575 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 7576 orntNew[3] = -2; 7577 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7578 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7579 #if defined(PETSC_USE_DEBUG) 7580 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7581 for (p = 0; p < 4; ++p) { 7582 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7583 } 7584 #endif 7585 /* C-D face */ 7586 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 7587 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 7588 orntNew[0] = 0; 7589 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7590 orntNew[1] = 0; 7591 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7592 orntNew[2] = -2; 7593 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 7594 orntNew[3] = -2; 7595 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7596 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7597 #if defined(PETSC_USE_DEBUG) 7598 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7599 for (p = 0; p < 4; ++p) { 7600 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7601 } 7602 #endif 7603 /* B-C face */ 7604 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 7605 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 7606 orntNew[0] = -2; 7607 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 7608 orntNew[1] = 0; 7609 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7610 orntNew[2] = 0; 7611 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7612 orntNew[3] = -2; 7613 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7614 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7615 #if defined(PETSC_USE_DEBUG) 7616 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7617 for (p = 0; p < 4; ++p) { 7618 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7619 } 7620 #endif 7621 /* A-B face */ 7622 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 7623 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 7624 orntNew[0] = -2; 7625 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 7626 orntNew[1] = 0; 7627 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7628 orntNew[2] = 0; 7629 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7630 orntNew[3] = -2; 7631 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7632 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7633 #if defined(PETSC_USE_DEBUG) 7634 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7635 for (p = 0; p < 4; ++p) { 7636 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7637 } 7638 #endif 7639 /* E-F face */ 7640 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 7641 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7642 orntNew[0] = -2; 7643 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 7644 orntNew[1] = -2; 7645 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 7646 orntNew[2] = 0; 7647 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7648 orntNew[3] = 0; 7649 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7650 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7651 #if defined(PETSC_USE_DEBUG) 7652 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7653 for (p = 0; p < 4; ++p) { 7654 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7655 } 7656 #endif 7657 /* F-G face */ 7658 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 7659 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7660 orntNew[0] = -2; 7661 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 7662 orntNew[1] = -2; 7663 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 7664 orntNew[2] = 0; 7665 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7666 orntNew[3] = 0; 7667 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7668 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7669 #if defined(PETSC_USE_DEBUG) 7670 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7671 for (p = 0; p < 4; ++p) { 7672 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); 7673 } 7674 #endif 7675 /* G-H face */ 7676 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 7677 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 7678 orntNew[0] = -2; 7679 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 7680 orntNew[1] = 0; 7681 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7682 orntNew[2] = 0; 7683 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7684 orntNew[3] = -2; 7685 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7686 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7687 #if defined(PETSC_USE_DEBUG) 7688 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7689 for (p = 0; p < 4; ++p) { 7690 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); 7691 } 7692 #endif 7693 /* E-H face */ 7694 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 7695 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7696 orntNew[0] = -2; 7697 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 7698 orntNew[1] = -2; 7699 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 7700 orntNew[2] = 0; 7701 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7702 orntNew[3] = 0; 7703 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7704 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7705 #if defined(PETSC_USE_DEBUG) 7706 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7707 for (p = 0; p < 4; ++p) { 7708 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); 7709 } 7710 #endif 7711 /* A-E face */ 7712 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 7713 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 7714 orntNew[0] = 0; 7715 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7716 orntNew[1] = 0; 7717 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7718 orntNew[2] = -2; 7719 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 7720 orntNew[3] = -2; 7721 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7722 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7723 #if defined(PETSC_USE_DEBUG) 7724 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7725 for (p = 0; p < 4; ++p) { 7726 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); 7727 } 7728 #endif 7729 /* D-F face */ 7730 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 7731 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7732 orntNew[0] = -2; 7733 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7734 orntNew[1] = 0; 7735 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7736 orntNew[2] = 0; 7737 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7738 orntNew[3] = -2; 7739 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7740 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7741 #if defined(PETSC_USE_DEBUG) 7742 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7743 for (p = 0; p < 4; ++p) { 7744 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); 7745 } 7746 #endif 7747 /* C-G face */ 7748 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 7749 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7750 orntNew[0] = -2; 7751 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7752 orntNew[1] = -2; 7753 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7754 orntNew[2] = 0; 7755 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7756 orntNew[3] = 0; 7757 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7758 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7759 #if defined(PETSC_USE_DEBUG) 7760 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7761 for (p = 0; p < 4; ++p) { 7762 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); 7763 } 7764 #endif 7765 /* B-H face */ 7766 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 7767 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7768 orntNew[0] = 0; 7769 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7770 orntNew[1] = -2; 7771 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7772 orntNew[2] = -2; 7773 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7774 orntNew[3] = 0; 7775 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7776 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7777 #if defined(PETSC_USE_DEBUG) 7778 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7779 for (p = 0; p < 4; ++p) { 7780 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); 7781 } 7782 #endif 7783 for (r = 0; r < 12; ++r) { 7784 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 7785 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7786 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7787 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7788 #if defined(PETSC_USE_DEBUG) 7789 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7790 for (p = 0; p < 2; ++p) { 7791 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); 7792 } 7793 #endif 7794 } 7795 } 7796 /* Hybrid split faces have 4 edges and same cells */ 7797 for (f = fMax; f < fEnd; ++f) { 7798 const PetscInt *cone, *ornt, *support; 7799 PetscInt coneNew[4], orntNew[4]; 7800 PetscInt supportNew[2], size, s, c; 7801 7802 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7803 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7804 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7805 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7806 for (r = 0; r < 2; ++r) { 7807 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 7808 7809 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 7810 orntNew[0] = ornt[0]; 7811 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 7812 orntNew[1] = ornt[1]; 7813 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 7814 orntNew[2+r] = 0; 7815 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7816 orntNew[3-r] = 0; 7817 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7818 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7819 #if defined(PETSC_USE_DEBUG) 7820 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7821 for (p = 0; p < 2; ++p) { 7822 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); 7823 } 7824 for (p = 2; p < 4; ++p) { 7825 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); 7826 } 7827 #endif 7828 for (s = 0; s < size; ++s) { 7829 const PetscInt *coneCell, *orntCell, *fornt; 7830 PetscInt o, of; 7831 7832 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7833 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7834 o = orntCell[0] < 0 ? -1 : 1; 7835 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 7836 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 7837 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 7838 of = fornt[c-2] < 0 ? -1 : 1; 7839 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 7840 } 7841 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7842 #if defined(PETSC_USE_DEBUG) 7843 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7844 for (p = 0; p < size; ++p) { 7845 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); 7846 } 7847 #endif 7848 } 7849 } 7850 /* Hybrid cell faces have 4 edges and 2 cells */ 7851 for (c = cMax; c < cEnd; ++c) { 7852 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 7853 const PetscInt *cone, *ornt; 7854 PetscInt coneNew[4], orntNew[4]; 7855 PetscInt supportNew[2]; 7856 7857 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7858 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7859 for (r = 0; r < 4; ++r) { 7860 #if 0 7861 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 7862 orntNew[0] = 0; 7863 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 7864 orntNew[1] = 0; 7865 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 7866 orntNew[2] = 0; 7867 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7868 orntNew[3] = 0; 7869 #else 7870 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 7871 orntNew[0] = 0; 7872 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 7873 orntNew[1] = 0; 7874 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 7875 orntNew[2] = 0; 7876 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7877 orntNew[3] = 0; 7878 #endif 7879 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7880 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7881 #if defined(PETSC_USE_DEBUG) 7882 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); 7883 for (p = 0; p < 2; ++p) { 7884 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); 7885 } 7886 for (p = 2; p < 4; ++p) { 7887 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); 7888 } 7889 #endif 7890 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 7891 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 7892 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 7893 #if defined(PETSC_USE_DEBUG) 7894 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); 7895 for (p = 0; p < 2; ++p) { 7896 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); 7897 } 7898 #endif 7899 } 7900 } 7901 /* Interior split edges have 2 vertices and the same faces as the parent */ 7902 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7903 for (e = eStart; e < eMax; ++e) { 7904 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7905 7906 for (r = 0; r < 2; ++r) { 7907 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7908 const PetscInt *cone, *ornt, *support; 7909 PetscInt coneNew[2], coneSize, c, supportSize, s; 7910 7911 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7912 coneNew[0] = vStartNew + (cone[0] - vStart); 7913 coneNew[1] = vStartNew + (cone[1] - vStart); 7914 coneNew[(r+1)%2] = newv; 7915 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7916 #if defined(PETSC_USE_DEBUG) 7917 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7918 for (p = 0; p < 2; ++p) { 7919 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); 7920 } 7921 #endif 7922 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7923 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7924 for (s = 0; s < supportSize; ++s) { 7925 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7926 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7927 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7928 for (c = 0; c < coneSize; ++c) { 7929 if (cone[c] == e) break; 7930 } 7931 if (support[s] < fMax) { 7932 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 7933 } else { 7934 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 7935 } 7936 } 7937 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7938 #if defined(PETSC_USE_DEBUG) 7939 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7940 for (p = 0; p < supportSize; ++p) { 7941 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); 7942 } 7943 #endif 7944 } 7945 } 7946 /* Interior face edges have 2 vertices and 2+cells faces */ 7947 for (f = fStart; f < fMax; ++f) { 7948 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}; 7949 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 7950 const PetscInt *cone, *coneCell, *orntCell, *support; 7951 PetscInt coneNew[2], coneSize, c, supportSize, s; 7952 7953 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7954 for (r = 0; r < 4; ++r) { 7955 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7956 7957 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7958 coneNew[1] = newv; 7959 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7960 #if defined(PETSC_USE_DEBUG) 7961 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7962 for (p = 0; p < 2; ++p) { 7963 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); 7964 } 7965 #endif 7966 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7967 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7968 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7969 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7970 for (s = 0; s < supportSize; ++s) { 7971 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7972 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7973 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7974 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7975 if (support[s] < cMax) { 7976 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7977 } else { 7978 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 7979 } 7980 } 7981 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7982 #if defined(PETSC_USE_DEBUG) 7983 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7984 for (p = 0; p < 2+supportSize; ++p) { 7985 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); 7986 } 7987 #endif 7988 } 7989 } 7990 /* Interior cell edges have 2 vertices and 4 faces */ 7991 for (c = cStart; c < cMax; ++c) { 7992 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}; 7993 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 7994 const PetscInt *cone; 7995 PetscInt coneNew[2], supportNew[4]; 7996 7997 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7998 for (r = 0; r < 6; ++r) { 7999 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8000 8001 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 8002 coneNew[1] = newv; 8003 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8004 #if defined(PETSC_USE_DEBUG) 8005 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 8006 for (p = 0; p < 2; ++p) { 8007 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); 8008 } 8009 #endif 8010 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 8011 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8012 #if defined(PETSC_USE_DEBUG) 8013 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 8014 for (p = 0; p < 4; ++p) { 8015 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); 8016 } 8017 #endif 8018 } 8019 } 8020 /* Hybrid edges have two vertices and the same faces */ 8021 for (e = eMax; e < eEnd; ++e) { 8022 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 8023 const PetscInt *cone, *support, *fcone; 8024 PetscInt coneNew[2], size, fsize, s; 8025 8026 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8027 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8028 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8029 coneNew[0] = vStartNew + (cone[0] - vStart); 8030 coneNew[1] = vStartNew + (cone[1] - vStart); 8031 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8032 #if defined(PETSC_USE_DEBUG) 8033 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8034 for (p = 0; p < 2; ++p) { 8035 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); 8036 } 8037 #endif 8038 for (s = 0; s < size; ++s) { 8039 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 8040 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 8041 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 8042 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 8043 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 8044 } 8045 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8046 #if defined(PETSC_USE_DEBUG) 8047 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8048 for (p = 0; p < size; ++p) { 8049 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); 8050 } 8051 #endif 8052 } 8053 /* Hybrid face edges have 2 vertices and 2+cells faces */ 8054 for (f = fMax; f < fEnd; ++f) { 8055 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 8056 const PetscInt *cone, *support, *ccone, *cornt; 8057 PetscInt coneNew[2], size, csize, s; 8058 8059 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 8060 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8061 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8062 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 8063 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 8064 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8065 #if defined(PETSC_USE_DEBUG) 8066 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8067 for (p = 0; p < 2; ++p) { 8068 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); 8069 } 8070 #endif 8071 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 8072 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 8073 for (s = 0; s < size; ++s) { 8074 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 8075 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 8076 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 8077 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 8078 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]); 8079 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 8080 } 8081 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8082 #if defined(PETSC_USE_DEBUG) 8083 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8084 for (p = 0; p < 2+size; ++p) { 8085 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); 8086 } 8087 #endif 8088 } 8089 /* Hybrid cell edges have 2 vertices and 4 faces */ 8090 for (c = cMax; c < cEnd; ++c) { 8091 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 8092 const PetscInt *cone, *support; 8093 PetscInt coneNew[2], size; 8094 8095 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8096 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 8097 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 8098 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 8099 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 8100 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8101 #if defined(PETSC_USE_DEBUG) 8102 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8103 for (p = 0; p < 2; ++p) { 8104 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); 8105 } 8106 #endif 8107 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 8108 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 8109 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 8110 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 8111 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8112 #if defined(PETSC_USE_DEBUG) 8113 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8114 for (p = 0; p < 4; ++p) { 8115 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); 8116 } 8117 #endif 8118 } 8119 /* Interior vertices have identical supports */ 8120 for (v = vStart; v < vEnd; ++v) { 8121 const PetscInt newp = vStartNew + (v - vStart); 8122 const PetscInt *support, *cone; 8123 PetscInt size, s; 8124 8125 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 8126 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 8127 for (s = 0; s < size; ++s) { 8128 PetscInt r = 0; 8129 8130 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8131 if (cone[1] == v) r = 1; 8132 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 8133 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 8134 } 8135 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8136 #if defined(PETSC_USE_DEBUG) 8137 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8138 for (p = 0; p < size; ++p) { 8139 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); 8140 } 8141 #endif 8142 } 8143 /* Interior edge vertices have 2 + faces supports */ 8144 for (e = eStart; e < eMax; ++e) { 8145 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 8146 const PetscInt *cone, *support; 8147 PetscInt size, s; 8148 8149 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8150 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8151 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 8152 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 8153 for (s = 0; s < size; ++s) { 8154 PetscInt r; 8155 8156 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8157 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 8158 if (support[s] < fMax) { 8159 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 8160 } else { 8161 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 8162 } 8163 } 8164 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8165 #if defined(PETSC_USE_DEBUG) 8166 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8167 for (p = 0; p < 2+size; ++p) { 8168 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); 8169 } 8170 #endif 8171 } 8172 /* Interior face vertices have 4 + cells supports */ 8173 for (f = fStart; f < fMax; ++f) { 8174 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8175 const PetscInt *cone, *support; 8176 PetscInt size, s; 8177 8178 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8179 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8180 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 8181 for (s = 0; s < size; ++s) { 8182 PetscInt r; 8183 8184 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8185 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 8186 if (support[s] < cMax) { 8187 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 8188 } else { 8189 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 8190 } 8191 } 8192 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8193 #if defined(PETSC_USE_DEBUG) 8194 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8195 for (p = 0; p < 4+size; ++p) { 8196 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); 8197 } 8198 #endif 8199 } 8200 /* Cell vertices have 6 supports */ 8201 for (c = cStart; c < cMax; ++c) { 8202 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 8203 PetscInt supportNew[6]; 8204 8205 for (r = 0; r < 6; ++r) { 8206 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8207 } 8208 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8209 } 8210 ierr = PetscFree(supportRef);CHKERRQ(ierr); 8211 break; 8212 default: 8213 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8214 } 8215 PetscFunctionReturn(0); 8216 } 8217 8218 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8219 { 8220 PetscSection coordSection, coordSectionNew; 8221 Vec coordinates, coordinatesNew; 8222 PetscScalar *coords, *coordsNew; 8223 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 8224 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 8225 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 8226 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 8227 VecType vtype; 8228 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 8229 const PetscReal *maxCell, *L; 8230 const DMBoundaryType *bd; 8231 PetscErrorCode ierr; 8232 8233 PetscFunctionBegin; 8234 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8235 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8236 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8237 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8238 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8239 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8240 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 8241 if (cMax < 0) cMax = cEnd; 8242 if (fMax < 0) fMax = fEnd; 8243 if (eMax < 0) eMax = eEnd; 8244 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 8245 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 8246 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 8247 /* Determine if we need to localize coordinates when generating them */ 8248 if (isperiodic && !maxCell) { 8249 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 8250 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 8251 } 8252 if (isperiodic) { 8253 ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr); 8254 ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr); 8255 ierr = PetscOptionsEnd();CHKERRQ(ierr); 8256 if (localize) { 8257 ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 8258 } 8259 } 8260 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 8261 8262 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 8263 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 8264 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 8265 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 8266 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 8267 8268 if (localize) { 8269 PetscInt p, r, newp, *pi; 8270 8271 /* New coordinates will be already localized on the cell */ 8272 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 8273 8274 /* We need the parentId to properly localize coordinates */ 8275 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 8276 switch (refiner) { 8277 case REFINER_NOOP: 8278 break; 8279 case REFINER_SIMPLEX_1D: 8280 for (p = cStart; p < cEnd; ++p) { 8281 for (r = 0; r < 2; ++r) { 8282 newp = (p - cStart)*2 + r; 8283 pi[newp] = p; 8284 } 8285 } 8286 break; 8287 case REFINER_SIMPLEX_2D: 8288 for (p = cStart; p < cEnd; ++p) { 8289 for (r = 0; r < 4; ++r) { 8290 newp = (p - cStart)*4 + r; 8291 pi[newp] = p; 8292 } 8293 } 8294 break; 8295 case REFINER_HEX_2D: 8296 for (p = cStart; p < cEnd; ++p) { 8297 for (r = 0; r < 4; ++r) { 8298 newp = (p - cStart)*4 + r; 8299 pi[newp] = p; 8300 } 8301 } 8302 break; 8303 case REFINER_SIMPLEX_TO_HEX_2D: 8304 for (p = cStart; p < cEnd; ++p) { 8305 for (r = 0; r < 3; ++r) { 8306 newp = (p - cStart)*3 + r; 8307 pi[newp] = p; 8308 } 8309 } 8310 break; 8311 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8312 for (p = cStart; p < cMax; ++p) { 8313 for (r = 0; r < 3; ++r) { 8314 newp = (p - cStart)*3 + r; 8315 pi[newp] = p; 8316 } 8317 } 8318 for (p = cMax; p < cEnd; ++p) { 8319 for (r = 0; r < 4; ++r) { 8320 newp = (cMax - cStart)*3 + (p - cMax)*4 + r; 8321 pi[newp] = p; 8322 } 8323 } 8324 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8325 cMax = cEnd; 8326 eMax = eEnd; 8327 break; 8328 case REFINER_HYBRID_SIMPLEX_2D: 8329 for (p = cStart; p < cMax; ++p) { 8330 for (r = 0; r < 4; ++r) { 8331 newp = (p - cStart)*4 + r; 8332 pi[newp] = p; 8333 } 8334 } 8335 for (p = cMax; p < cEnd; ++p) { 8336 for (r = 0; r < 2; ++r) { 8337 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8338 pi[newp] = p; 8339 } 8340 } 8341 break; 8342 case REFINER_HYBRID_HEX_2D: 8343 for (p = cStart; p < cMax; ++p) { 8344 for (r = 0; r < 4; ++r) { 8345 newp = (p - cStart)*4 + r; 8346 pi[newp] = p; 8347 } 8348 } 8349 for (p = cMax; p < cEnd; ++p) { 8350 for (r = 0; r < 2; ++r) { 8351 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8352 pi[newp] = p; 8353 } 8354 } 8355 break; 8356 case REFINER_SIMPLEX_3D: 8357 for (p = cStart; p < cEnd; ++p) { 8358 for (r = 0; r < 8; ++r) { 8359 newp = (p - cStart)*8 + r; 8360 pi[newp] = p; 8361 } 8362 } 8363 break; 8364 case REFINER_HYBRID_SIMPLEX_3D: 8365 for (p = cStart; p < cMax; ++p) { 8366 for (r = 0; r < 8; ++r) { 8367 newp = (p - cStart)*8 + r; 8368 pi[newp] = p; 8369 } 8370 } 8371 for (p = cMax; p < cEnd; ++p) { 8372 for (r = 0; r < 4; ++r) { 8373 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8374 pi[newp] = p; 8375 } 8376 } 8377 break; 8378 case REFINER_SIMPLEX_TO_HEX_3D: 8379 for (p = cStart; p < cEnd; ++p) { 8380 for (r = 0; r < 4; ++r) { 8381 newp = (p - cStart)*4 + r; 8382 pi[newp] = p; 8383 } 8384 } 8385 break; 8386 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8387 for (p = cStart; p < cMax; ++p) { 8388 for (r = 0; r < 4; ++r) { 8389 newp = (p - cStart)*4 + r; 8390 pi[newp] = p; 8391 } 8392 } 8393 for (p = cMax; p < cEnd; ++p) { 8394 for (r = 0; r < 3; ++r) { 8395 newp = (cMax - cStart)*4 + (p - cMax)*3 + r; 8396 pi[newp] = p; 8397 } 8398 } 8399 break; 8400 case REFINER_HEX_3D: 8401 for (p = cStart; p < cEnd; ++p) { 8402 for (r = 0; r < 8; ++r) { 8403 newp = (p - cStart)*8 + r; 8404 pi[newp] = p; 8405 } 8406 } 8407 break; 8408 case REFINER_HYBRID_HEX_3D: 8409 for (p = cStart; p < cMax; ++p) { 8410 for (r = 0; r < 8; ++r) { 8411 newp = (p - cStart)*8 + r; 8412 pi[newp] = p; 8413 } 8414 } 8415 for (p = cMax; p < cEnd; ++p) { 8416 for (r = 0; r < 4; ++r) { 8417 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8418 pi[newp] = p; 8419 } 8420 } 8421 break; 8422 default: 8423 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8424 } 8425 parentId = pi; 8426 } else { 8427 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8428 if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; } 8429 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 8430 } 8431 8432 /* All vertices have the spaceDim coordinates */ 8433 if (localize) { 8434 PetscInt c; 8435 8436 for (c = cStartNew; c < cEndNew; ++c) { 8437 PetscInt *cone = NULL; 8438 PetscInt closureSize, coneSize = 0, p, pdof; 8439 8440 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 8441 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 8442 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8443 for (p = 0; p < closureSize*2; p += 2) { 8444 const PetscInt point = cone[p]; 8445 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 8446 } 8447 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8448 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 8449 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 8450 } 8451 } 8452 } 8453 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 8454 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 8455 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 8456 } 8457 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 8458 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 8459 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8460 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 8461 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 8462 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 8463 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 8464 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 8465 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 8466 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 8467 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 8468 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 8469 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8470 8471 switch (refiner) { 8472 case REFINER_NOOP: break; 8473 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8474 case REFINER_SIMPLEX_TO_HEX_3D: 8475 case REFINER_HEX_3D: 8476 case REFINER_HYBRID_HEX_3D: 8477 /* Face vertices have the average of corner coordinates */ 8478 for (f = fStart; f < fMax; ++f) { 8479 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8480 PetscInt *cone = NULL; 8481 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 8482 8483 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8484 for (p = 0; p < closureSize*2; p += 2) { 8485 const PetscInt point = cone[p]; 8486 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8487 } 8488 if (localize) { 8489 const PetscInt *support = NULL; 8490 PetscInt *rStar = NULL; 8491 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 8492 PetscBool cellfound = PETSC_FALSE; 8493 8494 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8495 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 8496 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 8497 /* Compute average of coordinates for each cell sharing the face */ 8498 for (s = 0; s < supportSize; ++s) { 8499 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 8500 PetscInt *cellCone = NULL; 8501 PetscInt cellClosureSize, cellConeSize = 0, cdof; 8502 const PetscInt cell = support[s]; 8503 PetscBool copyoff = PETSC_FALSE; 8504 8505 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8506 for (p = 0; p < cellClosureSize*2; p += 2) { 8507 const PetscInt point = cellCone[p]; 8508 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 8509 } 8510 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8511 if (!cdof) { /* the parent cell does not have localized coordinates */ 8512 cellfound = PETSC_TRUE; 8513 for (v = 0; v < coneSize; ++v) { 8514 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8515 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 8516 } 8517 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8518 } else { 8519 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8520 for (p = 0; p < coneSize; ++p) { 8521 const PetscInt tv = cone[p]; 8522 PetscInt cv, voff; 8523 PetscBool locv = PETSC_TRUE; 8524 8525 for (cv = 0; cv < cellConeSize; ++cv) { 8526 if (cellCone[cv] == tv) { 8527 ccoff[p] = spaceDim*cv + coff; 8528 break; 8529 } 8530 } 8531 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D",tv); 8532 8533 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 8534 for (d = 0; d < spaceDim; ++d) { 8535 coordsNewAux[d] += coords[ccoff[p]+d]; 8536 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 8537 } 8538 if (locv && !cellfound) { 8539 cellfound = PETSC_TRUE; 8540 copyoff = PETSC_TRUE; 8541 } 8542 } 8543 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8544 8545 /* Found a valid face for the "vertex" part of the Section (physical space) 8546 i.e., a face that has at least one corner in the physical space */ 8547 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 8548 } 8549 8550 /* Localize new coordinates on each refined cell */ 8551 for (v = 0; v < rStarSize*2; v += 2) { 8552 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 8553 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 8554 const PetscInt rcell = rStar[v]; 8555 8556 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8557 if (!rcdof) continue; 8558 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 8559 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8560 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8561 if (rcone[p] == newv) { 8562 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 8563 break; 8564 } 8565 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8566 } 8567 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8568 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8569 } 8570 } 8571 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8572 } 8573 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8574 if (!cellfound) { 8575 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 8576 needcoords = PETSC_TRUE; 8577 coneSize = 0; 8578 } 8579 } else { 8580 for (v = 0; v < coneSize; ++v) { 8581 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8582 } 8583 } 8584 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8585 if (coneSize) { 8586 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8587 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8588 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8589 } else { 8590 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8591 } 8592 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8593 } 8594 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8595 case REFINER_SIMPLEX_TO_HEX_2D: 8596 case REFINER_HEX_2D: 8597 case REFINER_HYBRID_HEX_2D: 8598 case REFINER_SIMPLEX_1D: 8599 /* Cell vertices have the average of corner coordinates */ 8600 for (c = cStart; c < cMax; ++c) { 8601 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 8602 PetscInt *cone = NULL; 8603 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 8604 8605 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8606 for (p = 0; p < closureSize*2; p += 2) { 8607 const PetscInt point = cone[p]; 8608 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8609 } 8610 if (localize) { 8611 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 8612 } 8613 if (cdof) { 8614 PetscInt coff; 8615 8616 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 8617 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 8618 } else { 8619 for (v = 0; v < coneSize; ++v) { 8620 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8621 } 8622 } 8623 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8624 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8625 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8626 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8627 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8628 8629 /* Localize new coordinates on each refined cell */ 8630 if (cdof) { 8631 PetscInt *rStar = NULL, rStarSize; 8632 8633 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8634 for (v = 0; v < rStarSize*2; v += 2) { 8635 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 8636 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 8637 8638 rc = rStar[v]; 8639 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 8640 if (!rcdof) continue; 8641 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 8642 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8643 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 8644 if (cone[p] == newv) { 8645 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 8646 break; 8647 } 8648 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 8649 } 8650 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8651 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8652 } 8653 } 8654 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8655 } 8656 } 8657 case REFINER_SIMPLEX_2D: 8658 case REFINER_HYBRID_SIMPLEX_2D: 8659 case REFINER_SIMPLEX_3D: 8660 case REFINER_HYBRID_SIMPLEX_3D: 8661 /* Edge vertices have the average of endpoint coordinates */ 8662 for (e = eStart; e < eMax; ++e) { 8663 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 8664 const PetscInt *cone; 8665 PetscInt coneSize, offA, offB, offnew, d; 8666 8667 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 8668 if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 8669 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8670 if (localize) { 8671 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 8672 PetscInt *eStar = NULL, eStarSize; 8673 PetscInt *rStar = NULL, rStarSize; 8674 PetscBool cellfound = PETSC_FALSE; 8675 8676 offA = offB = -1; 8677 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 8678 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 8679 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8680 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8681 for (v = 0; v < eStarSize*2; v += 2) { 8682 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 8683 PetscScalar coordsNewAux[3]; 8684 PetscInt *cellCone = NULL; 8685 PetscInt cellClosureSize, s, cv, cdof; 8686 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 8687 const PetscInt cell = eStar[v]; 8688 8689 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8690 if (!cdof) { 8691 /* Found a valid edge for the "vertex" part of the Section */ 8692 offA = voffA; 8693 offB = voffB; 8694 cellfound = PETSC_TRUE; 8695 } else { 8696 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8697 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8698 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 8699 const PetscInt point = cellCone[s]; 8700 if ((point >= vStart) && (point < vEnd)) { 8701 if (point == cone[0]) toffA = spaceDim*cv + coff; 8702 else if (point == cone[1]) toffB = spaceDim*cv + coff; 8703 cv++; 8704 } 8705 } 8706 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8707 for (d = 0; d < spaceDim; ++d) { 8708 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 8709 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 8710 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 8711 } 8712 /* Found a valid edge for the "vertex" part of the Section */ 8713 if (!cellfound && (locvA || locvB)) { 8714 cellfound = PETSC_TRUE; 8715 offA = toffA; 8716 offB = toffB; 8717 } 8718 } 8719 8720 /* Localize new coordinates on each refined cell */ 8721 for (s = 0; s < rStarSize*2; s += 2) { 8722 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 8723 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 8724 const PetscInt rcell = rStar[s]; 8725 8726 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8727 if (!rcdof) continue; 8728 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 8729 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8730 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8731 if (rcone[p] == newv) { 8732 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 8733 break; 8734 } 8735 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8736 } 8737 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8738 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8739 } 8740 } 8741 } 8742 } 8743 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8744 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8745 if (!cellfound) { 8746 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 8747 needcoords = PETSC_TRUE; 8748 } 8749 } else { 8750 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 8751 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 8752 } 8753 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8754 if (offA != -1 && offB != -1) { 8755 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 8756 for (d = 0; d < spaceDim; ++d) { 8757 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 8758 } 8759 } else { 8760 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8761 } 8762 } 8763 /* Old vertices have the same coordinates */ 8764 for (v = vStart; v < vEnd; ++v) { 8765 const PetscInt newv = vStartNew + (v - vStart); 8766 PetscInt off, offnew, d; 8767 8768 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 8769 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8770 for (d = 0; d < spaceDim; ++d) { 8771 coordsNew[offnew+d] = coords[off+d]; 8772 } 8773 8774 /* Localize new coordinates on each refined cell */ 8775 if (localize) { 8776 PetscInt p; 8777 PetscInt *rStar = NULL, rStarSize; 8778 8779 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8780 for (p = 0; p < rStarSize*2; p += 2) { 8781 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 8782 PetscScalar ocoords[3]; 8783 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 8784 8785 c = rStar[p]; 8786 oc = parentId[c-cStartNew]; 8787 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 8788 if (!cdof) continue; 8789 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 8790 if (!cdof) continue; 8791 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 8792 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8793 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8794 if (cone[s] == v) { 8795 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 8796 break; 8797 } 8798 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 8799 } 8800 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D",v); 8801 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8802 8803 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 8804 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8805 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8806 if (cone[s] == newv) { 8807 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 8808 break; 8809 } 8810 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 8811 } 8812 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8813 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8814 } 8815 } 8816 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8817 } 8818 } 8819 break; 8820 default: 8821 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8822 } 8823 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 8824 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8825 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 8826 8827 /* Final reduction (if needed) if we are localizing */ 8828 if (localize) { 8829 PetscBool gred; 8830 8831 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 8832 if (gred) { 8833 DM cdm; 8834 Vec aux; 8835 PetscSF sf; 8836 const PetscScalar *lArray; 8837 PetscScalar *gArray; 8838 #if defined(PETSC_USE_COMPLEX) 8839 PetscInt i, ln, gn; 8840 PetscReal *lrArray; 8841 PetscReal *grArray; 8842 #endif 8843 8844 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 8845 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 8846 ierr = DMGetDefaultSF(cdm, &sf);CHKERRQ(ierr); 8847 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8848 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 8849 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 8850 #if defined(PETSC_USE_COMPLEX) 8851 ierr = VecGetLocalSize(aux, &gn);CHKERRQ(ierr); 8852 ierr = VecGetLocalSize(coordinatesNew, &ln);CHKERRQ(ierr); 8853 ierr = PetscMalloc2(ln,&lrArray,gn,&grArray);CHKERRQ(ierr); 8854 for (i=0;i<ln;i++) lrArray[i] = PetscRealPart(lArray[i]); 8855 for (i=0;i<gn;i++) grArray[i] = PetscRealPart(gArray[i]); 8856 ierr = PetscSFReduceBegin(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8857 ierr = PetscSFReduceEnd(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8858 for (i=0;i<gn;i++) gArray[i] = grArray[i]; 8859 ierr = PetscFree2(lrArray,grArray);CHKERRQ(ierr); 8860 #else 8861 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8862 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8863 #endif 8864 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8865 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 8866 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8867 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8868 ierr = VecDestroy(&aux);CHKERRQ(ierr); 8869 } 8870 } 8871 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 8872 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 8873 ierr = PetscFree(parentId);CHKERRQ(ierr); 8874 PetscFunctionReturn(0); 8875 } 8876 8877 /*@ 8878 DMPlexCreateProcessSF - Create an SF which just has process connectivity 8879 8880 Collective on DM 8881 8882 Input Parameters: 8883 + dm - The DM 8884 - sfPoint - The PetscSF which encodes point connectivity 8885 8886 Output Parameters: 8887 + processRanks - A list of process neighbors, or NULL 8888 - sfProcess - An SF encoding the process connectivity, or NULL 8889 8890 Level: developer 8891 8892 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 8893 @*/ 8894 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 8895 { 8896 PetscInt numRoots, numLeaves, l; 8897 const PetscInt *localPoints; 8898 const PetscSFNode *remotePoints; 8899 PetscInt *localPointsNew; 8900 PetscSFNode *remotePointsNew; 8901 PetscInt *ranks, *ranksNew; 8902 PetscMPIInt size; 8903 PetscErrorCode ierr; 8904 8905 PetscFunctionBegin; 8906 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8907 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 8908 if (processRanks) {PetscValidPointer(processRanks, 3);} 8909 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 8910 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 8911 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8912 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 8913 for (l = 0; l < numLeaves; ++l) { 8914 ranks[l] = remotePoints[l].rank; 8915 } 8916 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 8917 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 8918 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 8919 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 8920 for (l = 0; l < numLeaves; ++l) { 8921 ranksNew[l] = ranks[l]; 8922 localPointsNew[l] = l; 8923 remotePointsNew[l].index = 0; 8924 remotePointsNew[l].rank = ranksNew[l]; 8925 } 8926 ierr = PetscFree(ranks);CHKERRQ(ierr); 8927 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 8928 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 8929 if (sfProcess) { 8930 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 8931 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 8932 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 8933 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 8934 } 8935 PetscFunctionReturn(0); 8936 } 8937 8938 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8939 { 8940 PetscSF sf, sfNew, sfProcess; 8941 IS processRanks; 8942 MPI_Datatype depthType; 8943 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 8944 const PetscInt *localPoints, *neighbors; 8945 const PetscSFNode *remotePoints; 8946 PetscInt *localPointsNew; 8947 PetscSFNode *remotePointsNew; 8948 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 8949 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 8950 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8951 PetscErrorCode ierr; 8952 8953 PetscFunctionBegin; 8954 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 8955 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 8956 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 8957 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %D != %D", ldepth, depth); 8958 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8959 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8960 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8961 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8962 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 8963 cMax = cMax < 0 ? cEnd : cMax; 8964 fMax = fMax < 0 ? fEnd : fMax; 8965 eMax = eMax < 0 ? eEnd : eMax; 8966 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8967 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 8968 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 8969 /* Calculate size of new SF */ 8970 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8971 if (numRoots < 0) PetscFunctionReturn(0); 8972 for (l = 0; l < numLeaves; ++l) { 8973 const PetscInt p = localPoints[l]; 8974 8975 switch (refiner) { 8976 case REFINER_SIMPLEX_1D: 8977 if ((p >= vStart) && (p < vEnd)) { 8978 /* Interior vertices stay the same */ 8979 ++numLeavesNew; 8980 } else if ((p >= cStart && p < cMax)) { 8981 /* Interior cells add new cells and interior vertices */ 8982 numLeavesNew += 2 + 1; 8983 } 8984 break; 8985 case REFINER_SIMPLEX_2D: 8986 case REFINER_HYBRID_SIMPLEX_2D: 8987 if ((p >= vStart) && (p < vEnd)) { 8988 /* Interior vertices stay the same */ 8989 ++numLeavesNew; 8990 } else if ((p >= fStart) && (p < fMax)) { 8991 /* Interior faces add new faces and vertex */ 8992 numLeavesNew += 2 + 1; 8993 } else if ((p >= fMax) && (p < fEnd)) { 8994 /* Hybrid faces stay the same */ 8995 ++numLeavesNew; 8996 } else if ((p >= cStart) && (p < cMax)) { 8997 /* Interior cells add new cells and interior faces */ 8998 numLeavesNew += 4 + 3; 8999 } else if ((p >= cMax) && (p < cEnd)) { 9000 /* Hybrid cells add new cells and hybrid face */ 9001 numLeavesNew += 2 + 1; 9002 } 9003 break; 9004 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9005 case REFINER_SIMPLEX_TO_HEX_2D: 9006 if ((p >= vStart) && (p < vEnd)) { 9007 /* Interior vertices stay the same */ 9008 ++numLeavesNew; 9009 } else if ((p >= fStart) && (p < fEnd)) { 9010 /* Interior faces add new faces and vertex */ 9011 numLeavesNew += 2 + 1; 9012 } else if ((p >= cStart) && (p < cMax)) { 9013 /* Interior cells add new cells, interior faces, and vertex */ 9014 numLeavesNew += 3 + 3 + 1; 9015 } else if ((p >= cMax) && (p < cEnd)) { 9016 /* Hybrid cells add new cells, interior faces, and vertex */ 9017 numLeavesNew += 4 + 4 + 1; 9018 } 9019 break; 9020 case REFINER_HEX_2D: 9021 case REFINER_HYBRID_HEX_2D: 9022 if ((p >= vStart) && (p < vEnd)) { 9023 /* Interior vertices stay the same */ 9024 ++numLeavesNew; 9025 } else if ((p >= fStart) && (p < fMax)) { 9026 /* Interior faces add new faces and vertex */ 9027 numLeavesNew += 2 + 1; 9028 } else if ((p >= fMax) && (p < fEnd)) { 9029 /* Hybrid faces stay the same */ 9030 ++numLeavesNew; 9031 } else if ((p >= cStart) && (p < cMax)) { 9032 /* Interior cells add new cells, interior faces, and vertex */ 9033 numLeavesNew += 4 + 4 + 1; 9034 } else if ((p >= cMax) && (p < cEnd)) { 9035 /* Hybrid cells add new cells and hybrid face */ 9036 numLeavesNew += 2 + 1; 9037 } 9038 break; 9039 case REFINER_SIMPLEX_3D: 9040 case REFINER_HYBRID_SIMPLEX_3D: 9041 if ((p >= vStart) && (p < vEnd)) { 9042 /* Interior vertices stay the same */ 9043 ++numLeavesNew; 9044 } else if ((p >= eStart) && (p < eMax)) { 9045 /* Interior edges add new edges and vertex */ 9046 numLeavesNew += 2 + 1; 9047 } else if ((p >= eMax) && (p < eEnd)) { 9048 /* Hybrid edges stay the same */ 9049 ++numLeavesNew; 9050 } else if ((p >= fStart) && (p < fMax)) { 9051 /* Interior faces add new faces and edges */ 9052 numLeavesNew += 4 + 3; 9053 } else if ((p >= fMax) && (p < fEnd)) { 9054 /* Hybrid faces add new faces and edges */ 9055 numLeavesNew += 2 + 1; 9056 } else if ((p >= cStart) && (p < cMax)) { 9057 /* Interior cells add new cells, faces, and edges */ 9058 numLeavesNew += 8 + 8 + 1; 9059 } else if ((p >= cMax) && (p < cEnd)) { 9060 /* Hybrid cells add new cells and faces */ 9061 numLeavesNew += 4 + 3; 9062 } 9063 break; 9064 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9065 case REFINER_SIMPLEX_TO_HEX_3D: 9066 if ((p >= vStart) && (p < vEnd)) { 9067 /* Interior vertices stay the same */ 9068 ++numLeavesNew; 9069 } else if ((p >= eStart) && (p < eMax)) { 9070 /* Interior edges add new edges and vertex */ 9071 numLeavesNew += 2 + 1; 9072 } else if ((p >= eMax) && (p < eEnd)) { 9073 /* Hybrid edges stay the same */ 9074 ++numLeavesNew; 9075 } else if ((p >= fStart) && (p < fMax)) { 9076 /* Interior faces add new faces, edges and a vertex */ 9077 numLeavesNew += 3 + 3 + 1; 9078 } else if ((p >= fMax) && (p < fEnd)) { 9079 /* Hybrid faces add new faces and an edge */ 9080 numLeavesNew += 2 + 1; 9081 } else if ((p >= cStart) && (p < cMax)) { 9082 /* Interior cells add new cells, faces, edges and a vertex */ 9083 numLeavesNew += 4 + 6 + 4 + 1; 9084 } else if ((p >= cMax) && (p < cEnd)) { 9085 /* Hybrid cells add new cells, faces and an edge */ 9086 numLeavesNew += 3 + 3 + 1; 9087 } 9088 break; 9089 case REFINER_HEX_3D: 9090 case REFINER_HYBRID_HEX_3D: 9091 if ((p >= vStart) && (p < vEnd)) { 9092 /* Old vertices stay the same */ 9093 ++numLeavesNew; 9094 } else if ((p >= eStart) && (p < eMax)) { 9095 /* Interior edges add new edges, and vertex */ 9096 numLeavesNew += 2 + 1; 9097 } else if ((p >= eMax) && (p < eEnd)) { 9098 /* Hybrid edges stay the same */ 9099 ++numLeavesNew; 9100 } else if ((p >= fStart) && (p < fMax)) { 9101 /* Interior faces add new faces, edges, and vertex */ 9102 numLeavesNew += 4 + 4 + 1; 9103 } else if ((p >= fMax) && (p < fEnd)) { 9104 /* Hybrid faces add new faces and edges */ 9105 numLeavesNew += 2 + 1; 9106 } else if ((p >= cStart) && (p < cMax)) { 9107 /* Interior cells add new cells, faces, edges, and vertex */ 9108 numLeavesNew += 8 + 12 + 6 + 1; 9109 } else if ((p >= cStart) && (p < cEnd)) { 9110 /* Hybrid cells add new cells, faces, and edges */ 9111 numLeavesNew += 4 + 4 + 1; 9112 } 9113 break; 9114 default: 9115 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9116 } 9117 } 9118 /* Communicate depthSizes for each remote rank */ 9119 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 9120 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 9121 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 9122 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 9123 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 9124 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 9125 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9126 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9127 for (n = 0; n < numNeighbors; ++n) { 9128 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 9129 } 9130 depthSizeOld[depth] = cMax; 9131 depthSizeOld[0] = vMax; 9132 depthSizeOld[depth-1] = fMax; 9133 depthSizeOld[1] = eMax; 9134 9135 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9136 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9137 9138 depthSizeOld[depth] = cEnd - cStart; 9139 depthSizeOld[0] = vEnd - vStart; 9140 depthSizeOld[depth-1] = fEnd - fStart; 9141 depthSizeOld[1] = eEnd - eStart; 9142 9143 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9144 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9145 for (n = 0; n < numNeighbors; ++n) { 9146 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 9147 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 9148 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]; 9149 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 9150 } 9151 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 9152 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 9153 /* Calculate new point SF */ 9154 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 9155 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 9156 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 9157 for (l = 0, m = 0; l < numLeaves; ++l) { 9158 PetscInt p = localPoints[l]; 9159 PetscInt rp = remotePoints[l].index, n; 9160 PetscMPIInt rrank = remotePoints[l].rank; 9161 9162 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 9163 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rrank); 9164 switch (refiner) { 9165 case REFINER_SIMPLEX_1D: 9166 if ((p >= vStart) && (p < vEnd)) { 9167 /* Old vertices stay the same */ 9168 localPointsNew[m] = vStartNew + (p - vStart); 9169 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9170 remotePointsNew[m].rank = rrank; 9171 ++m; 9172 } else if ((p >= cStart) && (p < cMax)) { 9173 /* Old interior cells add new cells and vertex */ 9174 for (r = 0; r < 2; ++r, ++m) { 9175 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 9176 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 9177 remotePointsNew[m].rank = rrank; 9178 } 9179 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 9180 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 9181 remotePointsNew[m].rank = rrank; 9182 ++m; 9183 } 9184 break; 9185 case REFINER_SIMPLEX_2D: 9186 case REFINER_HYBRID_SIMPLEX_2D: 9187 if ((p >= vStart) && (p < vEnd)) { 9188 /* Old vertices stay the same */ 9189 localPointsNew[m] = vStartNew + (p - vStart); 9190 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9191 remotePointsNew[m].rank = rrank; 9192 ++m; 9193 } else if ((p >= fStart) && (p < fMax)) { 9194 /* Old interior faces add new faces and vertex */ 9195 for (r = 0; r < 2; ++r, ++m) { 9196 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9197 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9198 remotePointsNew[m].rank = rrank; 9199 } 9200 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9201 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9202 remotePointsNew[m].rank = rrank; 9203 ++m; 9204 } else if ((p >= fMax) && (p < fEnd)) { 9205 /* Old hybrid faces stay the same */ 9206 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9207 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9208 remotePointsNew[m].rank = rrank; 9209 ++m; 9210 } else if ((p >= cStart) && (p < cMax)) { 9211 /* Old interior cells add new cells and interior faces */ 9212 for (r = 0; r < 4; ++r, ++m) { 9213 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9214 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9215 remotePointsNew[m].rank = rrank; 9216 } 9217 for (r = 0; r < 3; ++r, ++m) { 9218 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 9219 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 9220 remotePointsNew[m].rank = rrank; 9221 } 9222 } else if ((p >= cMax) && (p < cEnd)) { 9223 /* Old hybrid cells add new cells and hybrid face */ 9224 for (r = 0; r < 2; ++r, ++m) { 9225 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9226 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9227 remotePointsNew[m].rank = rrank; 9228 } 9229 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9230 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]); 9231 remotePointsNew[m].rank = rrank; 9232 ++m; 9233 } 9234 break; 9235 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9236 case REFINER_SIMPLEX_TO_HEX_2D: 9237 if ((p >= vStart) && (p < vEnd)) { 9238 /* Old vertices stay the same */ 9239 localPointsNew[m] = vStartNew + (p - vStart); 9240 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9241 remotePointsNew[m].rank = rrank; 9242 ++m; 9243 } else if ((p >= fStart) && (p < fEnd)) { 9244 /* Old interior faces add new faces and vertex */ 9245 for (r = 0; r < 2; ++r, ++m) { 9246 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9247 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9248 remotePointsNew[m].rank = rrank; 9249 } 9250 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9251 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9252 remotePointsNew[m].rank = rrank; 9253 ++m; 9254 } else if ((p >= cStart) && (p < cMax)) { 9255 /* Old interior cells add new cells, interior faces, and a vertex */ 9256 for (r = 0; r < 3; ++r, ++m) { 9257 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 9258 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 9259 remotePointsNew[m].rank = rrank; 9260 } 9261 for (r = 0; r < 3; ++r, ++m) { 9262 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9263 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 9264 remotePointsNew[m].rank = rrank; 9265 } 9266 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9267 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9268 remotePointsNew[m].rank = rrank; 9269 ++m; 9270 } else if ((p >= cMax) && (p < cEnd)) { 9271 /* Old interior hybrid cells add new cells, interior faces, and a vertex */ 9272 for (r = 0; r < 4; ++r, ++m) { 9273 localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9274 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9275 remotePointsNew[m].rank = rrank; 9276 } 9277 for (r = 0; r < 4; ++r, ++m) { 9278 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9279 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; 9280 remotePointsNew[m].rank = rrank; 9281 } 9282 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9283 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9284 remotePointsNew[m].rank = rrank; 9285 ++m; 9286 } 9287 break; 9288 case REFINER_HEX_2D: 9289 case REFINER_HYBRID_HEX_2D: 9290 if ((p >= vStart) && (p < vEnd)) { 9291 /* Old vertices stay the same */ 9292 localPointsNew[m] = vStartNew + (p - vStart); 9293 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9294 remotePointsNew[m].rank = rrank; 9295 ++m; 9296 } else if ((p >= fStart) && (p < fMax)) { 9297 /* Old interior faces add new faces and vertex */ 9298 for (r = 0; r < 2; ++r, ++m) { 9299 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9300 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9301 remotePointsNew[m].rank = rrank; 9302 } 9303 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9304 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9305 remotePointsNew[m].rank = rrank; 9306 ++m; 9307 } else if ((p >= fMax) && (p < fEnd)) { 9308 /* Old hybrid faces stay the same */ 9309 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9310 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9311 remotePointsNew[m].rank = rrank; 9312 ++m; 9313 } else if ((p >= cStart) && (p < cMax)) { 9314 /* Old interior cells add new cells, interior faces, and vertex */ 9315 for (r = 0; r < 4; ++r, ++m) { 9316 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9317 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9318 remotePointsNew[m].rank = rrank; 9319 } 9320 for (r = 0; r < 4; ++r, ++m) { 9321 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 9322 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 9323 remotePointsNew[m].rank = rrank; 9324 } 9325 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 9326 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 9327 remotePointsNew[m].rank = rrank; 9328 ++m; 9329 } else if ((p >= cStart) && (p < cMax)) { 9330 /* Old hybrid cells add new cells and hybrid face */ 9331 for (r = 0; r < 2; ++r, ++m) { 9332 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */ 9333 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */ 9334 remotePointsNew[m].rank = rrank; 9335 } 9336 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9337 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]); 9338 remotePointsNew[m].rank = rrank; 9339 ++m; 9340 } 9341 break; 9342 case REFINER_SIMPLEX_3D: 9343 case REFINER_HYBRID_SIMPLEX_3D: 9344 if ((p >= vStart) && (p < vEnd)) { 9345 /* Interior vertices stay the same */ 9346 localPointsNew[m] = vStartNew + (p - vStart); 9347 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9348 remotePointsNew[m].rank = rrank; 9349 ++m; 9350 } else if ((p >= eStart) && (p < eMax)) { 9351 /* Interior edges add new edges and vertex */ 9352 for (r = 0; r < 2; ++r, ++m) { 9353 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9354 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9355 remotePointsNew[m].rank = rrank; 9356 } 9357 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9358 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9359 remotePointsNew[m].rank = rrank; 9360 ++m; 9361 } else if ((p >= eMax) && (p < eEnd)) { 9362 /* Hybrid edges stay the same */ 9363 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9364 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]); 9365 remotePointsNew[m].rank = rrank; 9366 ++m; 9367 } else if ((p >= fStart) && (p < fMax)) { 9368 /* Interior faces add new faces and edges */ 9369 for (r = 0; r < 4; ++r, ++m) { 9370 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9371 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9372 remotePointsNew[m].rank = rrank; 9373 } 9374 for (r = 0; r < 3; ++r, ++m) { 9375 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9376 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9377 remotePointsNew[m].rank = rrank; 9378 } 9379 } else if ((p >= fMax) && (p < fEnd)) { 9380 /* Hybrid faces add new faces and edges */ 9381 for (r = 0; r < 2; ++r, ++m) { 9382 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9383 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; 9384 remotePointsNew[m].rank = rrank; 9385 } 9386 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 9387 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]); 9388 remotePointsNew[m].rank = rrank; 9389 ++m; 9390 } else if ((p >= cStart) && (p < cMax)) { 9391 /* Interior cells add new cells, faces, and edges */ 9392 for (r = 0; r < 8; ++r, ++m) { 9393 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9394 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9395 remotePointsNew[m].rank = rrank; 9396 } 9397 for (r = 0; r < 8; ++r, ++m) { 9398 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9399 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 9400 remotePointsNew[m].rank = rrank; 9401 } 9402 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 9403 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; 9404 remotePointsNew[m].rank = rrank; 9405 ++m; 9406 } else if ((p >= cMax) && (p < cEnd)) { 9407 /* Hybrid cells add new cells and faces */ 9408 for (r = 0; r < 4; ++r, ++m) { 9409 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9410 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9411 remotePointsNew[m].rank = rrank; 9412 } 9413 for (r = 0; r < 3; ++r, ++m) { 9414 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9415 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; 9416 remotePointsNew[m].rank = rrank; 9417 } 9418 } 9419 break; 9420 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9421 case REFINER_SIMPLEX_TO_HEX_3D: 9422 if ((p >= vStart) && (p < vEnd)) { 9423 /* Interior vertices stay the same */ 9424 localPointsNew[m] = vStartNew + (p - vStart); 9425 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9426 remotePointsNew[m].rank = rrank; 9427 ++m; 9428 } else if ((p >= eStart) && (p < eMax)) { 9429 /* Interior edges add new edges and vertex */ 9430 for (r = 0; r < 2; ++r, ++m) { 9431 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9432 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9433 remotePointsNew[m].rank = rrank; 9434 } 9435 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9436 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9437 remotePointsNew[m].rank = rrank; 9438 ++m; 9439 } else if ((p >= eMax) && (p < eEnd)) { 9440 /* Hybrid edges stay the same */ 9441 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax); 9442 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]); 9443 remotePointsNew[m].rank = rrank; 9444 ++m; 9445 } else if ((p >= fStart) && (p < fMax)) { 9446 /* Interior faces add new faces, edges and a vertex */ 9447 for (r = 0; r < 3; ++r, ++m) { 9448 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 9449 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 9450 remotePointsNew[m].rank = rrank; 9451 } 9452 for (r = 0; r < 3; ++r, ++m) { 9453 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9454 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9455 remotePointsNew[m].rank = rrank; 9456 } 9457 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9458 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9459 remotePointsNew[m].rank = rrank; 9460 ++m; 9461 } else if ((p >= fMax) && (p < fEnd)) { 9462 /* Interior hybrid faces add new faces and an edge */ 9463 for (r = 0; r < 2; ++r, ++m) { 9464 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9465 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; 9466 remotePointsNew[m].rank = rrank; 9467 } 9468 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9469 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]); 9470 remotePointsNew[m].rank = rrank; 9471 ++m; 9472 } else if ((p >= cStart) && (p < cMax)) { 9473 /* Interior cells add new cells, faces, edges, and a vertex */ 9474 for (r = 0; r < 4; ++r, ++m) { 9475 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9476 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9477 remotePointsNew[m].rank = rrank; 9478 } 9479 for (r = 0; r < 6; ++r, ++m) { 9480 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9481 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r; 9482 remotePointsNew[m].rank = rrank; 9483 } 9484 for (r = 0; r < 4; ++r, ++m) { 9485 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9486 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; 9487 remotePointsNew[m].rank = rrank; 9488 } 9489 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 9490 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]); 9491 remotePointsNew[m].rank = rrank; 9492 ++m; 9493 } else if ((p >= cMax) && (p < cEnd)) { 9494 /* Interior hybrid cells add new cells, faces and an edge */ 9495 for (r = 0; r < 3; ++r, ++m) { 9496 localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9497 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9498 remotePointsNew[m].rank = rrank; 9499 } 9500 for (r = 0; r < 3; ++r, ++m) { 9501 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9502 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; 9503 remotePointsNew[m].rank = rrank; 9504 } 9505 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9506 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]); 9507 remotePointsNew[m].rank = rrank; 9508 ++m; 9509 } 9510 break; 9511 case REFINER_HEX_3D: 9512 case REFINER_HYBRID_HEX_3D: 9513 if ((p >= vStart) && (p < vEnd)) { 9514 /* Interior vertices stay the same */ 9515 localPointsNew[m] = vStartNew + (p - vStart); 9516 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9517 remotePointsNew[m].rank = rrank; 9518 ++m; 9519 } else if ((p >= eStart) && (p < eMax)) { 9520 /* Interior edges add new edges and vertex */ 9521 for (r = 0; r < 2; ++r, ++m) { 9522 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9523 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9524 remotePointsNew[m].rank = rrank; 9525 } 9526 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9527 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9528 remotePointsNew[m].rank = rrank; 9529 ++m; 9530 } else if ((p >= eMax) && (p < eEnd)) { 9531 /* Hybrid edges stay the same */ 9532 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 9533 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]); 9534 remotePointsNew[m].rank = rrank; 9535 ++m; 9536 } else if ((p >= fStart) && (p < fMax)) { 9537 /* Interior faces add new faces, edges, and vertex */ 9538 for (r = 0; r < 4; ++r, ++m) { 9539 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9540 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9541 remotePointsNew[m].rank = rrank; 9542 } 9543 for (r = 0; r < 4; ++r, ++m) { 9544 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 9545 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 9546 remotePointsNew[m].rank = rrank; 9547 } 9548 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9549 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9550 remotePointsNew[m].rank = rrank; 9551 ++m; 9552 } else if ((p >= fMax) && (p < fEnd)) { 9553 /* Hybrid faces add new faces and edges */ 9554 for (r = 0; r < 2; ++r, ++m) { 9555 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 9556 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; 9557 remotePointsNew[m].rank = rrank; 9558 } 9559 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 9560 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]); 9561 remotePointsNew[m].rank = rrank; 9562 ++m; 9563 } else if ((p >= cStart) && (p < cMax)) { 9564 /* Interior cells add new cells, faces, edges, and vertex */ 9565 for (r = 0; r < 8; ++r, ++m) { 9566 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9567 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9568 remotePointsNew[m].rank = rrank; 9569 } 9570 for (r = 0; r < 12; ++r, ++m) { 9571 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 9572 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 9573 remotePointsNew[m].rank = rrank; 9574 } 9575 for (r = 0; r < 6; ++r, ++m) { 9576 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 9577 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; 9578 remotePointsNew[m].rank = rrank; 9579 } 9580 for (r = 0; r < 1; ++r, ++m) { 9581 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 9582 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 9583 remotePointsNew[m].rank = rrank; 9584 } 9585 } else if ((p >= cMax) && (p < cEnd)) { 9586 /* Hybrid cells add new cells, faces, and edges */ 9587 for (r = 0; r < 4; ++r, ++m) { 9588 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9589 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9590 remotePointsNew[m].rank = rrank; 9591 } 9592 for (r = 0; r < 4; ++r, ++m) { 9593 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 9594 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; 9595 remotePointsNew[m].rank = rrank; 9596 } 9597 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9598 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]); 9599 remotePointsNew[m].rank = rrank; 9600 ++m; 9601 } 9602 break; 9603 default: 9604 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9605 } 9606 } 9607 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 9608 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 9609 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 9610 { 9611 PetscSFNode *rp, *rtmp; 9612 PetscInt *lp, *idx, *ltmp, i; 9613 9614 /* SF needs sorted leaves to correct calculate Gather */ 9615 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 9616 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 9617 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 9618 for (i = 0; i < numLeavesNew; ++i) { 9619 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); 9620 idx[i] = i; 9621 } 9622 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 9623 for (i = 0; i < numLeavesNew; ++i) { 9624 lp[i] = localPointsNew[idx[i]]; 9625 rp[i] = remotePointsNew[idx[i]]; 9626 } 9627 ltmp = localPointsNew; 9628 localPointsNew = lp; 9629 rtmp = remotePointsNew; 9630 remotePointsNew = rp; 9631 ierr = PetscFree(idx);CHKERRQ(ierr); 9632 ierr = PetscFree(ltmp);CHKERRQ(ierr); 9633 ierr = PetscFree(rtmp);CHKERRQ(ierr); 9634 } 9635 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 9636 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 9637 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 9638 PetscFunctionReturn(0); 9639 } 9640 9641 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 9642 { 9643 PetscInt numLabels, l; 9644 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 9645 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 9646 PetscErrorCode ierr; 9647 9648 PetscFunctionBegin; 9649 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 9650 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 9651 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9652 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 9653 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 9654 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 9655 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 9656 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 9657 switch (refiner) { 9658 case REFINER_NOOP: 9659 case REFINER_SIMPLEX_1D: 9660 case REFINER_SIMPLEX_2D: 9661 case REFINER_SIMPLEX_TO_HEX_2D: 9662 case REFINER_HEX_2D: 9663 case REFINER_SIMPLEX_3D: 9664 case REFINER_HEX_3D: 9665 case REFINER_SIMPLEX_TO_HEX_3D: 9666 break; 9667 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9668 case REFINER_HYBRID_SIMPLEX_3D: 9669 case REFINER_HYBRID_HEX_3D: 9670 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 9671 case REFINER_HYBRID_SIMPLEX_2D: 9672 case REFINER_HYBRID_HEX_2D: 9673 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 9674 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9675 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 9676 break; 9677 default: 9678 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9679 } 9680 cMax = cMax < 0 ? cEnd : cMax; 9681 fMax = fMax < 0 ? fEnd : fMax; 9682 eMax = eMax < 0 ? eEnd : eMax; 9683 for (l = 0; l < numLabels; ++l) { 9684 DMLabel label, labelNew; 9685 const char *lname; 9686 PetscBool isDepth; 9687 IS valueIS; 9688 const PetscInt *values; 9689 PetscInt defVal; 9690 PetscInt numValues, val; 9691 9692 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 9693 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 9694 if (isDepth) continue; 9695 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 9696 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 9697 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 9698 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 9699 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 9700 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 9701 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 9702 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 9703 for (val = 0; val < numValues; ++val) { 9704 IS pointIS; 9705 const PetscInt *points; 9706 PetscInt numPoints, n; 9707 9708 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 9709 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 9710 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 9711 /* Ensure refined label is created with same number of strata as 9712 * original (even if no entries here). */ 9713 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 9714 for (n = 0; n < numPoints; ++n) { 9715 const PetscInt p = points[n]; 9716 switch (refiner) { 9717 case REFINER_SIMPLEX_1D: 9718 if ((p >= vStart) && (p < vEnd)) { 9719 /* Old vertices stay the same */ 9720 newp = vStartNew + (p - vStart); 9721 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9722 } else if ((p >= cStart) && (p < cEnd)) { 9723 /* Old cells add new cells and vertex */ 9724 newp = vStartNew + (vEnd - vStart) + (p - cStart); 9725 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9726 for (r = 0; r < 2; ++r) { 9727 newp = cStartNew + (p - cStart)*2 + r; 9728 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9729 } 9730 } 9731 break; 9732 case REFINER_SIMPLEX_2D: 9733 if ((p >= vStart) && (p < vEnd)) { 9734 /* Old vertices stay the same */ 9735 newp = vStartNew + (p - vStart); 9736 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9737 } else if ((p >= fStart) && (p < fEnd)) { 9738 /* Old faces add new faces and vertex */ 9739 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9740 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9741 for (r = 0; r < 2; ++r) { 9742 newp = fStartNew + (p - fStart)*2 + r; 9743 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9744 } 9745 } else if ((p >= cStart) && (p < cEnd)) { 9746 /* Old cells add new cells and interior faces */ 9747 for (r = 0; r < 4; ++r) { 9748 newp = cStartNew + (p - cStart)*4 + r; 9749 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9750 } 9751 for (r = 0; r < 3; ++r) { 9752 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9753 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9754 } 9755 } 9756 break; 9757 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9758 case REFINER_SIMPLEX_TO_HEX_2D: 9759 if ((p >= vStart) && (p < vEnd)) { 9760 /* Old vertices stay the same */ 9761 newp = vStartNew + (p - vStart); 9762 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9763 } else if ((p >= fStart) && (p < fEnd)) { 9764 /* Old faces add new faces and vertex */ 9765 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9766 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9767 for (r = 0; r < 2; ++r) { 9768 newp = fStartNew + (p - fStart)*2 + r; 9769 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9770 } 9771 } else if ((p >= cStart) && (p < cMax)) { 9772 /* Old cells add new cells, interior faces, and a vertex */ 9773 for (r = 0; r < 3; ++r) { 9774 newp = cStartNew + (p - cStart)*3 + r; 9775 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9776 } 9777 for (r = 0; r < 3; ++r) { 9778 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9779 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9780 } 9781 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9782 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9783 } else if ((p >= cMax) && (p < cEnd)) { 9784 /* Old hybrid cells add new cells, interior faces, and a vertex */ 9785 for (r = 0; r < 4; ++r) { 9786 newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9787 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9788 } 9789 for (r = 0; r < 4; ++r) { 9790 newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9791 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9792 } 9793 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9794 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9795 } 9796 break; 9797 case REFINER_HEX_2D: 9798 if ((p >= vStart) && (p < vEnd)) { 9799 /* Old vertices stay the same */ 9800 newp = vStartNew + (p - vStart); 9801 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9802 } else if ((p >= fStart) && (p < fEnd)) { 9803 /* Old faces add new faces and vertex */ 9804 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9805 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9806 for (r = 0; r < 2; ++r) { 9807 newp = fStartNew + (p - fStart)*2 + r; 9808 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9809 } 9810 } else if ((p >= cStart) && (p < cEnd)) { 9811 /* Old cells add new cells and interior faces and vertex */ 9812 for (r = 0; r < 4; ++r) { 9813 newp = cStartNew + (p - cStart)*4 + r; 9814 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9815 } 9816 for (r = 0; r < 4; ++r) { 9817 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9818 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9819 } 9820 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9821 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9822 } 9823 break; 9824 case REFINER_HYBRID_SIMPLEX_2D: 9825 if ((p >= vStart) && (p < vEnd)) { 9826 /* Old vertices stay the same */ 9827 newp = vStartNew + (p - vStart); 9828 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9829 } else if ((p >= fStart) && (p < fMax)) { 9830 /* Old interior faces add new faces and vertex */ 9831 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9832 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9833 for (r = 0; r < 2; ++r) { 9834 newp = fStartNew + (p - fStart)*2 + r; 9835 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9836 } 9837 } else if ((p >= fMax) && (p < fEnd)) { 9838 /* Old hybrid faces stay the same */ 9839 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9840 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9841 } else if ((p >= cStart) && (p < cMax)) { 9842 /* Old interior cells add new cells and interior faces */ 9843 for (r = 0; r < 4; ++r) { 9844 newp = cStartNew + (p - cStart)*4 + r; 9845 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9846 } 9847 for (r = 0; r < 3; ++r) { 9848 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9849 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9850 } 9851 } else if ((p >= cMax) && (p < cEnd)) { 9852 /* Old hybrid cells add new cells and hybrid face */ 9853 for (r = 0; r < 2; ++r) { 9854 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9855 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9856 } 9857 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9858 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9859 } 9860 break; 9861 case REFINER_HYBRID_HEX_2D: 9862 if ((p >= vStart) && (p < vEnd)) { 9863 /* Old vertices stay the same */ 9864 newp = vStartNew + (p - vStart); 9865 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9866 } else if ((p >= fStart) && (p < fMax)) { 9867 /* Old interior faces add new faces and vertex */ 9868 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9869 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9870 for (r = 0; r < 2; ++r) { 9871 newp = fStartNew + (p - fStart)*2 + r; 9872 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9873 } 9874 } else if ((p >= fMax) && (p < fEnd)) { 9875 /* Old hybrid faces stay the same */ 9876 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9877 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9878 } else if ((p >= cStart) && (p < cMax)) { 9879 /* Old interior cells add new cells, interior faces, and vertex */ 9880 for (r = 0; r < 4; ++r) { 9881 newp = cStartNew + (p - cStart)*4 + r; 9882 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9883 } 9884 for (r = 0; r < 4; ++r) { 9885 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9886 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9887 } 9888 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9889 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9890 } else if ((p >= cMax) && (p < cEnd)) { 9891 /* Old hybrid cells add new cells and hybrid face */ 9892 for (r = 0; r < 2; ++r) { 9893 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9894 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9895 } 9896 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9897 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9898 } 9899 break; 9900 case REFINER_SIMPLEX_3D: 9901 if ((p >= vStart) && (p < vEnd)) { 9902 /* Old vertices stay the same */ 9903 newp = vStartNew + (p - vStart); 9904 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9905 } else if ((p >= eStart) && (p < eEnd)) { 9906 /* Old edges add new edges and vertex */ 9907 for (r = 0; r < 2; ++r) { 9908 newp = eStartNew + (p - eStart)*2 + r; 9909 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9910 } 9911 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9912 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9913 } else if ((p >= fStart) && (p < fEnd)) { 9914 /* Old faces add new faces and edges */ 9915 for (r = 0; r < 4; ++r) { 9916 newp = fStartNew + (p - fStart)*4 + r; 9917 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9918 } 9919 for (r = 0; r < 3; ++r) { 9920 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 9921 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9922 } 9923 } else if ((p >= cStart) && (p < cEnd)) { 9924 /* Old cells add new cells and interior faces and edges */ 9925 for (r = 0; r < 8; ++r) { 9926 newp = cStartNew + (p - cStart)*8 + r; 9927 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9928 } 9929 for (r = 0; r < 8; ++r) { 9930 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 9931 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9932 } 9933 for (r = 0; r < 1; ++r) { 9934 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 9935 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9936 } 9937 } 9938 break; 9939 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9940 case REFINER_SIMPLEX_TO_HEX_3D: 9941 if ((p >= vStart) && (p < vEnd)) { 9942 /* Old vertices stay the same */ 9943 newp = vStartNew + (p - vStart); 9944 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9945 } else if ((p >= eStart) && (p < eMax)) { 9946 /* Interior edges add new edges and vertex */ 9947 for (r = 0; r < 2; ++r) { 9948 newp = eStartNew + (p - eStart)*2 + r; 9949 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9950 } 9951 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9952 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9953 } else if ((p >= eMax) && (p < eEnd)) { 9954 /* Hybrid edges stay the same */ 9955 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax; 9956 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9957 } else if ((p >= fStart) && (p < fMax)) { 9958 /* Old faces add new faces, edges and a vertex */ 9959 for (r = 0; r < 3; ++r) { 9960 newp = fStartNew + (p - fStart)*3 + r; 9961 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9962 } 9963 for (r = 0; r < 3; ++r) { 9964 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9965 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9966 } 9967 } else if ((p >= fMax) && (p < fEnd)) { 9968 /* Old hybrid faces add new faces and an edge */ 9969 for (r = 0; r < 2; ++r) { 9970 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9971 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9972 } 9973 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9974 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9975 } else if ((p >= cStart) && (p < cMax)) { 9976 /* Old cells add new cells and interior faces and edges and a vertex */ 9977 for (r = 0; r < 4; ++r) { 9978 newp = cStartNew + (p - cStart)*4 + r; 9979 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9980 } 9981 for (r = 0; r < 6; ++r) { 9982 newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9983 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9984 } 9985 for (r = 0; r < 4; ++r) { 9986 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9987 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9988 } 9989 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart; 9990 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9991 } else if ((p >= cMax) && (p < cEnd)) { 9992 /* Old hybrid cells add new cells and interior faces and an edge */ 9993 for (r = 0; r < 3; ++r) { 9994 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9995 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9996 } 9997 for (r = 0; r < 3; ++r) { 9998 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9999 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10000 } 10001 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax; 10002 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10003 } 10004 break; 10005 case REFINER_HYBRID_SIMPLEX_3D: 10006 if ((p >= vStart) && (p < vEnd)) { 10007 /* Interior vertices stay the same */ 10008 newp = vStartNew + (p - vStart); 10009 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10010 } else if ((p >= eStart) && (p < eMax)) { 10011 /* Interior edges add new edges and vertex */ 10012 for (r = 0; r < 2; ++r) { 10013 newp = eStartNew + (p - eStart)*2 + r; 10014 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10015 } 10016 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10017 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10018 } else if ((p >= eMax) && (p < eEnd)) { 10019 /* Hybrid edges stay the same */ 10020 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 10021 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10022 } else if ((p >= fStart) && (p < fMax)) { 10023 /* Interior faces add new faces and edges */ 10024 for (r = 0; r < 4; ++r) { 10025 newp = fStartNew + (p - fStart)*4 + r; 10026 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10027 } 10028 for (r = 0; r < 3; ++r) { 10029 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 10030 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10031 } 10032 } else if ((p >= fMax) && (p < fEnd)) { 10033 /* Hybrid faces add new faces and edges */ 10034 for (r = 0; r < 2; ++r) { 10035 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 10036 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10037 } 10038 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 10039 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10040 } else if ((p >= cStart) && (p < cMax)) { 10041 /* Interior cells add new cells, faces, and edges */ 10042 for (r = 0; r < 8; ++r) { 10043 newp = cStartNew + (p - cStart)*8 + r; 10044 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10045 } 10046 for (r = 0; r < 8; ++r) { 10047 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 10048 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10049 } 10050 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 10051 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10052 } else if ((p >= cMax) && (p < cEnd)) { 10053 /* Hybrid cells add new cells and faces */ 10054 for (r = 0; r < 4; ++r) { 10055 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10056 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10057 } 10058 for (r = 0; r < 3; ++r) { 10059 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 10060 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10061 } 10062 } 10063 break; 10064 case REFINER_HEX_3D: 10065 if ((p >= vStart) && (p < vEnd)) { 10066 /* Old vertices stay the same */ 10067 newp = vStartNew + (p - vStart); 10068 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10069 } else if ((p >= eStart) && (p < eEnd)) { 10070 /* Old edges add new edges and vertex */ 10071 for (r = 0; r < 2; ++r) { 10072 newp = eStartNew + (p - eStart)*2 + r; 10073 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10074 } 10075 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10076 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10077 } else if ((p >= fStart) && (p < fEnd)) { 10078 /* Old faces add new faces, edges, and vertex */ 10079 for (r = 0; r < 4; ++r) { 10080 newp = fStartNew + (p - fStart)*4 + r; 10081 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10082 } 10083 for (r = 0; r < 4; ++r) { 10084 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 10085 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10086 } 10087 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 10088 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10089 } else if ((p >= cStart) && (p < cEnd)) { 10090 /* Old cells add new cells, faces, edges, and vertex */ 10091 for (r = 0; r < 8; ++r) { 10092 newp = cStartNew + (p - cStart)*8 + r; 10093 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10094 } 10095 for (r = 0; r < 12; ++r) { 10096 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 10097 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10098 } 10099 for (r = 0; r < 6; ++r) { 10100 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 10101 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10102 } 10103 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 10104 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10105 } 10106 break; 10107 case REFINER_HYBRID_HEX_3D: 10108 if ((p >= vStart) && (p < vEnd)) { 10109 /* Interior vertices stay the same */ 10110 newp = vStartNew + (p - vStart); 10111 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10112 } else if ((p >= eStart) && (p < eMax)) { 10113 /* Interior edges add new edges and vertex */ 10114 for (r = 0; r < 2; ++r) { 10115 newp = eStartNew + (p - eStart)*2 + r; 10116 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10117 } 10118 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10119 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10120 } else if ((p >= eMax) && (p < eEnd)) { 10121 /* Hybrid edges stay the same */ 10122 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 10123 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10124 } else if ((p >= fStart) && (p < fMax)) { 10125 /* Interior faces add new faces, edges, and vertex */ 10126 for (r = 0; r < 4; ++r) { 10127 newp = fStartNew + (p - fStart)*4 + r; 10128 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10129 } 10130 for (r = 0; r < 4; ++r) { 10131 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 10132 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10133 } 10134 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 10135 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10136 } else if ((p >= fMax) && (p < fEnd)) { 10137 /* Hybrid faces add new faces and edges */ 10138 for (r = 0; r < 2; ++r) { 10139 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 10140 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10141 } 10142 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 10143 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10144 } else if ((p >= cStart) && (p < cMax)) { 10145 /* Interior cells add new cells, faces, edges, and vertex */ 10146 for (r = 0; r < 8; ++r) { 10147 newp = cStartNew + (p - cStart)*8 + r; 10148 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10149 } 10150 for (r = 0; r < 12; ++r) { 10151 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 10152 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10153 } 10154 for (r = 0; r < 6; ++r) { 10155 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 10156 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10157 } 10158 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 10159 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10160 } else if ((p >= cMax) && (p < cEnd)) { 10161 /* Hybrid cells add new cells, faces, and edges */ 10162 for (r = 0; r < 4; ++r) { 10163 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10164 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10165 } 10166 for (r = 0; r < 4; ++r) { 10167 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 10168 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10169 } 10170 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 10171 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10172 } 10173 break; 10174 default: 10175 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 10176 } 10177 } 10178 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 10179 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 10180 } 10181 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 10182 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 10183 if (0) { 10184 ierr = DMLabelView(labelNew, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); 10185 } 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