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, celltypeLabel; 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 { 1731 DM_Plex *plex = (DM_Plex *) rdm->data; 1732 1733 ierr = DMPlexGetCellTypeLabel(rdm, &celltypeLabel);CHKERRQ(ierr); 1734 ierr = PetscObjectStateGet((PetscObject) celltypeLabel, &plex->celltypeState);CHKERRQ(ierr); 1735 } 1736 PetscFunctionReturn(0); 1737 } 1738 1739 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1740 { 1741 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1742 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1743 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1744 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r; 1745 #if defined(PETSC_USE_DEBUG) 1746 PetscInt p; 1747 #endif 1748 PetscErrorCode ierr; 1749 1750 PetscFunctionBegin; 1751 if (!refiner) PetscFunctionReturn(0); 1752 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1753 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1754 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1755 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1756 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1757 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1758 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1759 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1760 switch (refiner) { 1761 case REFINER_SIMPLEX_1D: 1762 /* Max support size of refined mesh is 2 */ 1763 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1764 /* All cells have 2 vertices */ 1765 for (c = cStart; c < cEnd; ++c) { 1766 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1767 1768 for (r = 0; r < 2; ++r) { 1769 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1770 const PetscInt *cone; 1771 PetscInt coneNew[2]; 1772 1773 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1774 coneNew[0] = vStartNew + (cone[0] - vStart); 1775 coneNew[1] = vStartNew + (cone[1] - vStart); 1776 coneNew[(r+1)%2] = newv; 1777 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1778 #if defined(PETSC_USE_DEBUG) 1779 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp, cStartNew, cEndNew); 1780 for (p = 0; p < 2; ++p) { 1781 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); 1782 } 1783 #endif 1784 } 1785 } 1786 /* Old vertices have identical supports */ 1787 for (v = vStart; v < vEnd; ++v) { 1788 const PetscInt newp = vStartNew + (v - vStart); 1789 const PetscInt *support, *cone; 1790 PetscInt size, s; 1791 1792 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1793 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1794 for (s = 0; s < size; ++s) { 1795 PetscInt r = 0; 1796 1797 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1798 if (cone[1] == v) r = 1; 1799 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1800 } 1801 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1802 #if defined(PETSC_USE_DEBUG) 1803 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1804 for (p = 0; p < size; ++p) { 1805 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); 1806 } 1807 #endif 1808 } 1809 /* Cell vertices have support of 2 cells */ 1810 for (c = cStart; c < cEnd; ++c) { 1811 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1812 1813 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1814 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1815 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1816 #if defined(PETSC_USE_DEBUG) 1817 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1818 for (p = 0; p < 2; ++p) { 1819 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); 1820 } 1821 #endif 1822 } 1823 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1824 break; 1825 case REFINER_SIMPLEX_2D: 1826 /* 1827 2 1828 |\ 1829 | \ 1830 | \ 1831 | \ 1832 | C \ 1833 | \ 1834 | \ 1835 2---1---1 1836 |\ D / \ 1837 | 2 0 \ 1838 |A \ / B \ 1839 0---0-------1 1840 */ 1841 /* All cells have 3 faces */ 1842 for (c = cStart; c < cEnd; ++c) { 1843 const PetscInt newp = cStartNew + (c - cStart)*4; 1844 const PetscInt *cone, *ornt; 1845 PetscInt coneNew[3], orntNew[3]; 1846 1847 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1848 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1849 /* A triangle */ 1850 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1851 orntNew[0] = ornt[0]; 1852 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1853 orntNew[1] = -2; 1854 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1855 orntNew[2] = ornt[2]; 1856 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1857 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1858 #if defined(PETSC_USE_DEBUG) 1859 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); 1860 for (p = 0; p < 3; ++p) { 1861 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); 1862 } 1863 #endif 1864 /* B triangle */ 1865 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1866 orntNew[0] = ornt[0]; 1867 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1868 orntNew[1] = ornt[1]; 1869 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1870 orntNew[2] = -2; 1871 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1872 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1873 #if defined(PETSC_USE_DEBUG) 1874 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); 1875 for (p = 0; p < 3; ++p) { 1876 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); 1877 } 1878 #endif 1879 /* C triangle */ 1880 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1881 orntNew[0] = -2; 1882 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1883 orntNew[1] = ornt[1]; 1884 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1885 orntNew[2] = ornt[2]; 1886 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1887 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1888 #if defined(PETSC_USE_DEBUG) 1889 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); 1890 for (p = 0; p < 3; ++p) { 1891 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); 1892 } 1893 #endif 1894 /* D triangle */ 1895 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1896 orntNew[0] = 0; 1897 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1898 orntNew[1] = 0; 1899 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1900 orntNew[2] = 0; 1901 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1902 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1903 #if defined(PETSC_USE_DEBUG) 1904 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); 1905 for (p = 0; p < 3; ++p) { 1906 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); 1907 } 1908 #endif 1909 } 1910 /* Split faces have 2 vertices and the same cells as the parent */ 1911 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1912 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1913 for (f = fStart; f < fEnd; ++f) { 1914 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1915 1916 for (r = 0; r < 2; ++r) { 1917 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1918 const PetscInt *cone, *ornt, *support; 1919 PetscInt coneNew[2], coneSize, c, supportSize, s; 1920 1921 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1922 coneNew[0] = vStartNew + (cone[0] - vStart); 1923 coneNew[1] = vStartNew + (cone[1] - vStart); 1924 coneNew[(r+1)%2] = newv; 1925 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1926 #if defined(PETSC_USE_DEBUG) 1927 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1928 for (p = 0; p < 2; ++p) { 1929 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); 1930 } 1931 #endif 1932 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1933 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1934 for (s = 0; s < supportSize; ++s) { 1935 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1936 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1937 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1938 for (c = 0; c < coneSize; ++c) { 1939 if (cone[c] == f) break; 1940 } 1941 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1942 } 1943 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1944 #if defined(PETSC_USE_DEBUG) 1945 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1946 for (p = 0; p < supportSize; ++p) { 1947 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); 1948 } 1949 #endif 1950 } 1951 } 1952 /* Interior faces have 2 vertices and 2 cells */ 1953 for (c = cStart; c < cEnd; ++c) { 1954 const PetscInt *cone; 1955 1956 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1957 for (r = 0; r < 3; ++r) { 1958 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1959 PetscInt coneNew[2]; 1960 PetscInt supportNew[2]; 1961 1962 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1963 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1964 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1965 #if defined(PETSC_USE_DEBUG) 1966 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1967 for (p = 0; p < 2; ++p) { 1968 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); 1969 } 1970 #endif 1971 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1972 supportNew[1] = (c - cStart)*4 + 3; 1973 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1974 #if defined(PETSC_USE_DEBUG) 1975 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1976 for (p = 0; p < 2; ++p) { 1977 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); 1978 } 1979 #endif 1980 } 1981 } 1982 /* Old vertices have identical supports */ 1983 for (v = vStart; v < vEnd; ++v) { 1984 const PetscInt newp = vStartNew + (v - vStart); 1985 const PetscInt *support, *cone; 1986 PetscInt size, s; 1987 1988 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1989 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1990 for (s = 0; s < size; ++s) { 1991 PetscInt r = 0; 1992 1993 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1994 if (cone[1] == v) r = 1; 1995 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1996 } 1997 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1998 #if defined(PETSC_USE_DEBUG) 1999 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2000 for (p = 0; p < size; ++p) { 2001 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); 2002 } 2003 #endif 2004 } 2005 /* Face vertices have 2 + cells*2 supports */ 2006 for (f = fStart; f < fEnd; ++f) { 2007 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2008 const PetscInt *cone, *support; 2009 PetscInt size, s; 2010 2011 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2012 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2013 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2014 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2015 for (s = 0; s < size; ++s) { 2016 PetscInt r = 0; 2017 2018 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2019 if (cone[1] == f) r = 1; 2020 else if (cone[2] == f) r = 2; 2021 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 2022 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2023 } 2024 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2025 #if defined(PETSC_USE_DEBUG) 2026 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2027 for (p = 0; p < 2+size*2; ++p) { 2028 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); 2029 } 2030 #endif 2031 } 2032 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2033 break; 2034 case REFINER_SIMPLEX_TO_HEX_2D: 2035 /* 2036 2 2037 |\ 2038 | \ 2039 | \ 2040 | \ 2041 | C \ 2042 | \ 2043 2 1 2044 |\ / \ 2045 | 2 1 \ 2046 | \/ \ 2047 | | \ 2048 |A | B \ 2049 | 0 \ 2050 | | \ 2051 0---0----------1 2052 */ 2053 /* All cells have 4 faces */ 2054 for (c = cStart; c < cEnd; ++c) { 2055 const PetscInt newp = cStartNew + (c - cStart)*3; 2056 const PetscInt *cone, *ornt; 2057 PetscInt coneNew[4], orntNew[4]; 2058 2059 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2060 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2061 /* A quad */ 2062 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2063 orntNew[0] = ornt[0]; 2064 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2065 orntNew[1] = 0; 2066 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2067 orntNew[2] = -2; 2068 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2069 orntNew[3] = ornt[2]; 2070 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2071 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2072 #if defined(PETSC_USE_DEBUG) 2073 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); 2074 for (p = 0; p < 4; ++p) { 2075 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); 2076 } 2077 #endif 2078 /* B quad */ 2079 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2080 orntNew[0] = ornt[0]; 2081 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2082 orntNew[1] = ornt[1]; 2083 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2084 orntNew[2] = 0; 2085 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2086 orntNew[3] = -2; 2087 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2088 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2089 #if defined(PETSC_USE_DEBUG) 2090 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); 2091 for (p = 0; p < 4; ++p) { 2092 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); 2093 } 2094 #endif 2095 /* C quad */ 2096 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2097 orntNew[0] = ornt[1]; 2098 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2099 orntNew[1] = ornt[2]; 2100 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2101 orntNew[2] = 0; 2102 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2103 orntNew[3] = -2; 2104 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2105 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2106 #if defined(PETSC_USE_DEBUG) 2107 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); 2108 for (p = 0; p < 4; ++p) { 2109 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); 2110 } 2111 #endif 2112 } 2113 /* Split faces have 2 vertices and the same cells as the parent */ 2114 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2115 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2116 for (f = fStart; f < fEnd; ++f) { 2117 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2118 2119 for (r = 0; r < 2; ++r) { 2120 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2121 const PetscInt *cone, *ornt, *support; 2122 PetscInt coneNew[2], coneSize, c, supportSize, s; 2123 2124 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2125 coneNew[0] = vStartNew + (cone[0] - vStart); 2126 coneNew[1] = vStartNew + (cone[1] - vStart); 2127 coneNew[(r+1)%2] = newv; 2128 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2129 #if defined(PETSC_USE_DEBUG) 2130 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2131 for (p = 0; p < 2; ++p) { 2132 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); 2133 } 2134 #endif 2135 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2136 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2137 for (s = 0; s < supportSize; ++s) { 2138 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2139 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2140 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2141 for (c = 0; c < coneSize; ++c) { 2142 if (cone[c] == f) break; 2143 } 2144 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2145 } 2146 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2147 #if defined(PETSC_USE_DEBUG) 2148 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2149 for (p = 0; p < supportSize; ++p) { 2150 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); 2151 } 2152 #endif 2153 } 2154 } 2155 /* Interior faces have 2 vertices and 2 cells */ 2156 for (c = cStart; c < cEnd; ++c) { 2157 const PetscInt *cone; 2158 2159 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2160 for (r = 0; r < 3; ++r) { 2161 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2162 PetscInt coneNew[2]; 2163 PetscInt supportNew[2]; 2164 2165 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2166 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2167 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2168 #if defined(PETSC_USE_DEBUG) 2169 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2170 for (p = 0; p < 2; ++p) { 2171 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); 2172 } 2173 #endif 2174 supportNew[0] = (c - cStart)*3 + r%3; 2175 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2176 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2177 #if defined(PETSC_USE_DEBUG) 2178 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2179 for (p = 0; p < 2; ++p) { 2180 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); 2181 } 2182 #endif 2183 } 2184 } 2185 /* Old vertices have identical supports */ 2186 for (v = vStart; v < vEnd; ++v) { 2187 const PetscInt newp = vStartNew + (v - vStart); 2188 const PetscInt *support, *cone; 2189 PetscInt size, s; 2190 2191 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2192 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2193 for (s = 0; s < size; ++s) { 2194 PetscInt r = 0; 2195 2196 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2197 if (cone[1] == v) r = 1; 2198 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2199 } 2200 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2201 #if defined(PETSC_USE_DEBUG) 2202 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2203 for (p = 0; p < size; ++p) { 2204 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); 2205 } 2206 #endif 2207 } 2208 /* Split-face vertices have cells + 2 supports */ 2209 for (f = fStart; f < fEnd; ++f) { 2210 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2211 const PetscInt *cone, *support; 2212 PetscInt size, s; 2213 2214 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2215 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2216 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2217 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2218 for (s = 0; s < size; ++s) { 2219 PetscInt r = 0; 2220 2221 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2222 if (cone[1] == f) r = 1; 2223 else if (cone[2] == f) r = 2; 2224 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2225 } 2226 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2227 #if defined(PETSC_USE_DEBUG) 2228 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2229 for (p = 0; p < 2+size; ++p) { 2230 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); 2231 } 2232 #endif 2233 } 2234 /* Interior vertices have 3 supports */ 2235 for (c = cStart; c < cEnd; ++c) { 2236 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2237 2238 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2239 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2240 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2241 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2242 } 2243 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2244 break; 2245 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 2246 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2247 cMax = PetscMin(cEnd, cMax); 2248 for (c = cStart; c < cMax; ++c) { 2249 const PetscInt newp = cStartNew + (c - cStart)*3; 2250 const PetscInt *cone, *ornt; 2251 PetscInt coneNew[4], orntNew[4]; 2252 2253 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2254 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2255 /* A quad */ 2256 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2257 orntNew[0] = ornt[0]; 2258 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2259 orntNew[1] = 0; 2260 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2261 orntNew[2] = -2; 2262 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2263 orntNew[3] = ornt[2]; 2264 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2265 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2266 #if defined(PETSC_USE_DEBUG) 2267 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); 2268 for (p = 0; p < 4; ++p) { 2269 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); 2270 } 2271 #endif 2272 /* B quad */ 2273 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2274 orntNew[0] = ornt[0]; 2275 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2276 orntNew[1] = ornt[1]; 2277 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2278 orntNew[2] = 0; 2279 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2280 orntNew[3] = -2; 2281 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2282 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2283 #if defined(PETSC_USE_DEBUG) 2284 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); 2285 for (p = 0; p < 4; ++p) { 2286 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); 2287 } 2288 #endif 2289 /* C quad */ 2290 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2291 orntNew[0] = ornt[1]; 2292 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2293 orntNew[1] = ornt[2]; 2294 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2295 orntNew[2] = 0; 2296 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2297 orntNew[3] = -2; 2298 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2299 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2300 #if defined(PETSC_USE_DEBUG) 2301 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); 2302 for (p = 0; p < 4; ++p) { 2303 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); 2304 } 2305 #endif 2306 } 2307 /* 2308 2---------1---------3 2309 | | | 2310 | D 1 C | 2311 | | | 2312 2----2----0----3----3 2313 | | | 2314 | A 0 B | 2315 | | | 2316 0---------0---------1 2317 */ 2318 /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */ 2319 for (c = cMax; c < cEnd; ++c) { 2320 const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4; 2321 const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4; 2322 const PetscInt *cone, *ornt; 2323 PetscInt coneNew[4], orntNew[4]; 2324 2325 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2326 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2327 /* A quad */ 2328 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2329 orntNew[0] = ornt[0]; 2330 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2331 orntNew[1] = 0; 2332 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2333 orntNew[2] = -2; 2334 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2335 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2336 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2337 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2338 #if defined(PETSC_USE_DEBUG) 2339 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); 2340 for (p = 0; p < 4; ++p) { 2341 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); 2342 } 2343 #endif 2344 /* B quad */ 2345 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2346 orntNew[0] = ornt[0]; 2347 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2348 orntNew[1] = ornt[3]; 2349 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2350 orntNew[2] = 0; 2351 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2352 orntNew[3] = -2; 2353 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2354 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2355 #if defined(PETSC_USE_DEBUG) 2356 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); 2357 for (p = 0; p < 4; ++p) { 2358 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); 2359 } 2360 #endif 2361 /* C quad */ 2362 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2363 orntNew[0] = -2; 2364 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2365 orntNew[1] = ornt[3]; 2366 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2367 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2368 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2369 orntNew[3] = 0; 2370 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2371 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2372 #if defined(PETSC_USE_DEBUG) 2373 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); 2374 for (p = 0; p < 4; ++p) { 2375 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); 2376 } 2377 #endif 2378 /* D quad */ 2379 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2380 orntNew[0] = 0; 2381 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2382 orntNew[1] = -2; 2383 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2384 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2385 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2386 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2387 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2388 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2389 #if defined(PETSC_USE_DEBUG) 2390 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); 2391 for (p = 0; p < 4; ++p) { 2392 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); 2393 } 2394 #endif 2395 } 2396 /* Split faces have 2 vertices and the same cells as the parent */ 2397 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2398 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2399 for (f = fStart; f < fEnd; ++f) { 2400 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2401 2402 for (r = 0; r < 2; ++r) { 2403 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2404 const PetscInt *cone, *ornt, *support; 2405 PetscInt coneNew[2], coneSize, c, supportSize, s; 2406 2407 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2408 coneNew[0] = vStartNew + (cone[0] - vStart); 2409 coneNew[1] = vStartNew + (cone[1] - vStart); 2410 coneNew[(r+1)%2] = newv; 2411 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2412 #if defined(PETSC_USE_DEBUG) 2413 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2414 for (p = 0; p < 2; ++p) { 2415 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); 2416 } 2417 #endif 2418 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2419 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2420 for (s = 0; s < supportSize; ++s) { 2421 const PetscInt p2q[4][2] = { {0, 1}, 2422 {3, 2}, 2423 {0, 3}, 2424 {1, 2} }; 2425 2426 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2427 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2428 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2429 for (c = 0; c < coneSize; ++c) { 2430 if (cone[c] == f) break; 2431 } 2432 if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2433 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]); 2434 else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2435 } 2436 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2437 #if defined(PETSC_USE_DEBUG) 2438 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2439 for (p = 0; p < supportSize; ++p) { 2440 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); 2441 } 2442 #endif 2443 } 2444 } 2445 /* Interior faces have 2 vertices and 2 cells */ 2446 for (c = cStart; c < cMax; ++c) { 2447 const PetscInt *cone; 2448 2449 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2450 for (r = 0; r < 3; ++r) { 2451 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2452 PetscInt coneNew[2]; 2453 PetscInt supportNew[2]; 2454 2455 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2456 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2457 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2458 #if defined(PETSC_USE_DEBUG) 2459 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2460 for (p = 0; p < 2; ++p) { 2461 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); 2462 } 2463 #endif 2464 supportNew[0] = (c - cStart)*3 + r%3; 2465 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2466 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2467 #if defined(PETSC_USE_DEBUG) 2468 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2469 for (p = 0; p < 2; ++p) { 2470 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); 2471 } 2472 #endif 2473 } 2474 } 2475 /* Hybrid interior faces have 2 vertices and 2 cells */ 2476 for (c = cMax; c < cEnd; ++c) { 2477 const PetscInt *cone; 2478 PetscInt coneNew[2], supportNew[2]; 2479 2480 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2481 for (r = 0; r < 4; ++r) { 2482 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 2483 2484 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2485 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax); 2486 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2487 #if defined(PETSC_USE_DEBUG) 2488 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2489 for (p = 0; p < 2; ++p) { 2490 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); 2491 } 2492 #endif 2493 if (r==0) { 2494 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2495 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2496 } else if (r==1) { 2497 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2498 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2499 } else if (r==2) { 2500 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2501 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2502 } else { 2503 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2504 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2505 } 2506 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2507 #if defined(PETSC_USE_DEBUG) 2508 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2509 for (p = 0; p < 2; ++p) { 2510 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); 2511 } 2512 #endif 2513 } 2514 } 2515 /* Old vertices have identical supports */ 2516 for (v = vStart; v < vEnd; ++v) { 2517 const PetscInt newp = vStartNew + (v - vStart); 2518 const PetscInt *support, *cone; 2519 PetscInt size, s; 2520 2521 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2522 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2523 for (s = 0; s < size; ++s) { 2524 PetscInt r = 0; 2525 2526 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2527 if (cone[1] == v) r = 1; 2528 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2529 } 2530 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2531 #if defined(PETSC_USE_DEBUG) 2532 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2533 for (p = 0; p < size; ++p) { 2534 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); 2535 } 2536 #endif 2537 } 2538 /* Split-face vertices have cells + 2 supports */ 2539 for (f = fStart; f < fEnd; ++f) { 2540 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2541 const PetscInt *cone, *support; 2542 PetscInt size, s; 2543 2544 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2545 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2546 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2547 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2548 for (s = 0; s < size; ++s) { 2549 PetscInt r = 0, coneSize; 2550 2551 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2552 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2553 if (coneSize == 3) { 2554 if (cone[1] == f) r = 1; 2555 else if (cone[2] == f) r = 2; 2556 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2557 } else if (coneSize == 4) { 2558 if (cone[1] == f) r = 1; 2559 else if (cone[2] == f) r = 2; 2560 else if (cone[3] == f) r = 3; 2561 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r; 2562 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2563 } 2564 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2565 #if defined(PETSC_USE_DEBUG) 2566 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2567 for (p = 0; p < 2+size; ++p) { 2568 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); 2569 } 2570 #endif 2571 } 2572 /* Interior vertices have 3 supports */ 2573 for (c = cStart; c < cMax; ++c) { 2574 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2575 2576 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2577 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2578 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2579 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2580 } 2581 /* Hybrid interior vertices have 4 supports */ 2582 for (c = cMax; c < cEnd; ++c) { 2583 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2584 2585 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0; 2586 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1; 2587 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2; 2588 supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3; 2589 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2590 } 2591 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2592 break; 2593 case REFINER_HEX_2D: 2594 /* 2595 3---------2---------2 2596 | | | 2597 | D 2 C | 2598 | | | 2599 3----3----0----1----1 2600 | | | 2601 | A 0 B | 2602 | | | 2603 0---------0---------1 2604 */ 2605 /* All cells have 4 faces */ 2606 for (c = cStart; c < cEnd; ++c) { 2607 const PetscInt newp = (c - cStart)*4; 2608 const PetscInt *cone, *ornt; 2609 PetscInt coneNew[4], orntNew[4]; 2610 2611 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2612 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2613 /* A quad */ 2614 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2615 orntNew[0] = ornt[0]; 2616 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2617 orntNew[1] = 0; 2618 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2619 orntNew[2] = -2; 2620 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2621 orntNew[3] = ornt[3]; 2622 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2623 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2624 #if defined(PETSC_USE_DEBUG) 2625 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); 2626 for (p = 0; p < 4; ++p) { 2627 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); 2628 } 2629 #endif 2630 /* B quad */ 2631 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2632 orntNew[0] = ornt[0]; 2633 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2634 orntNew[1] = ornt[1]; 2635 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2636 orntNew[2] = -2; 2637 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2638 orntNew[3] = -2; 2639 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2640 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2641 #if defined(PETSC_USE_DEBUG) 2642 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); 2643 for (p = 0; p < 4; ++p) { 2644 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); 2645 } 2646 #endif 2647 /* C quad */ 2648 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2649 orntNew[0] = 0; 2650 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2651 orntNew[1] = ornt[1]; 2652 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2653 orntNew[2] = ornt[2]; 2654 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2655 orntNew[3] = -2; 2656 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2657 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2658 #if defined(PETSC_USE_DEBUG) 2659 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); 2660 for (p = 0; p < 4; ++p) { 2661 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); 2662 } 2663 #endif 2664 /* D quad */ 2665 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2666 orntNew[0] = 0; 2667 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2668 orntNew[1] = 0; 2669 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2670 orntNew[2] = ornt[2]; 2671 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2672 orntNew[3] = ornt[3]; 2673 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2674 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2675 #if defined(PETSC_USE_DEBUG) 2676 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); 2677 for (p = 0; p < 4; ++p) { 2678 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); 2679 } 2680 #endif 2681 } 2682 /* Split faces have 2 vertices and the same cells as the parent */ 2683 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2684 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2685 for (f = fStart; f < fEnd; ++f) { 2686 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2687 2688 for (r = 0; r < 2; ++r) { 2689 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2690 const PetscInt *cone, *ornt, *support; 2691 PetscInt coneNew[2], coneSize, c, supportSize, s; 2692 2693 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2694 coneNew[0] = vStartNew + (cone[0] - vStart); 2695 coneNew[1] = vStartNew + (cone[1] - vStart); 2696 coneNew[(r+1)%2] = newv; 2697 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2698 #if defined(PETSC_USE_DEBUG) 2699 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2700 for (p = 0; p < 2; ++p) { 2701 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); 2702 } 2703 #endif 2704 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2705 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2706 for (s = 0; s < supportSize; ++s) { 2707 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2708 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2709 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2710 for (c = 0; c < coneSize; ++c) { 2711 if (cone[c] == f) break; 2712 } 2713 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2714 } 2715 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2716 #if defined(PETSC_USE_DEBUG) 2717 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2718 for (p = 0; p < supportSize; ++p) { 2719 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); 2720 } 2721 #endif 2722 } 2723 } 2724 /* Interior faces have 2 vertices and 2 cells */ 2725 for (c = cStart; c < cEnd; ++c) { 2726 const PetscInt *cone; 2727 PetscInt coneNew[2], supportNew[2]; 2728 2729 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2730 for (r = 0; r < 4; ++r) { 2731 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2732 2733 if (r==1 || r==2) { 2734 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2735 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2736 } else { 2737 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2738 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2739 } 2740 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2741 #if defined(PETSC_USE_DEBUG) 2742 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2743 for (p = 0; p < 2; ++p) { 2744 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); 2745 } 2746 #endif 2747 supportNew[0] = (c - cStart)*4 + r; 2748 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2749 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2750 #if defined(PETSC_USE_DEBUG) 2751 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2752 for (p = 0; p < 2; ++p) { 2753 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); 2754 } 2755 #endif 2756 } 2757 } 2758 /* Old vertices have identical supports */ 2759 for (v = vStart; v < vEnd; ++v) { 2760 const PetscInt newp = vStartNew + (v - vStart); 2761 const PetscInt *support, *cone; 2762 PetscInt size, s; 2763 2764 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2765 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2766 for (s = 0; s < size; ++s) { 2767 PetscInt r = 0; 2768 2769 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2770 if (cone[1] == v) r = 1; 2771 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2772 } 2773 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2774 #if defined(PETSC_USE_DEBUG) 2775 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2776 for (p = 0; p < size; ++p) { 2777 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); 2778 } 2779 #endif 2780 } 2781 /* Face vertices have 2 + cells supports */ 2782 for (f = fStart; f < fEnd; ++f) { 2783 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2784 const PetscInt *cone, *support; 2785 PetscInt size, s; 2786 2787 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2788 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2789 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2790 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2791 for (s = 0; s < size; ++s) { 2792 PetscInt r = 0; 2793 2794 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2795 if (cone[1] == f) r = 1; 2796 else if (cone[2] == f) r = 2; 2797 else if (cone[3] == f) r = 3; 2798 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 2799 } 2800 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2801 #if defined(PETSC_USE_DEBUG) 2802 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2803 for (p = 0; p < 2+size; ++p) { 2804 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); 2805 } 2806 #endif 2807 } 2808 /* Cell vertices have 4 supports */ 2809 for (c = cStart; c < cEnd; ++c) { 2810 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2811 PetscInt supportNew[4]; 2812 2813 for (r = 0; r < 4; ++r) { 2814 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2815 } 2816 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2817 } 2818 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2819 break; 2820 case REFINER_HYBRID_SIMPLEX_2D: 2821 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2822 cMax = PetscMin(cEnd, cMax); 2823 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2824 fMax = PetscMin(fEnd, fMax); 2825 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2826 /* Interior cells have 3 faces */ 2827 for (c = cStart; c < cMax; ++c) { 2828 const PetscInt newp = cStartNew + (c - cStart)*4; 2829 const PetscInt *cone, *ornt; 2830 PetscInt coneNew[3], orntNew[3]; 2831 2832 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2833 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2834 /* A triangle */ 2835 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2836 orntNew[0] = ornt[0]; 2837 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2838 orntNew[1] = -2; 2839 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2840 orntNew[2] = ornt[2]; 2841 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2842 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2843 #if defined(PETSC_USE_DEBUG) 2844 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); 2845 for (p = 0; p < 3; ++p) { 2846 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); 2847 } 2848 #endif 2849 /* B triangle */ 2850 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2851 orntNew[0] = ornt[0]; 2852 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2853 orntNew[1] = ornt[1]; 2854 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2855 orntNew[2] = -2; 2856 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2857 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2858 #if defined(PETSC_USE_DEBUG) 2859 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); 2860 for (p = 0; p < 3; ++p) { 2861 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); 2862 } 2863 #endif 2864 /* C triangle */ 2865 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2866 orntNew[0] = -2; 2867 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2868 orntNew[1] = ornt[1]; 2869 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2870 orntNew[2] = ornt[2]; 2871 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2872 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2873 #if defined(PETSC_USE_DEBUG) 2874 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); 2875 for (p = 0; p < 3; ++p) { 2876 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); 2877 } 2878 #endif 2879 /* D triangle */ 2880 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2881 orntNew[0] = 0; 2882 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2883 orntNew[1] = 0; 2884 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2885 orntNew[2] = 0; 2886 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2887 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2888 #if defined(PETSC_USE_DEBUG) 2889 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); 2890 for (p = 0; p < 3; ++p) { 2891 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); 2892 } 2893 #endif 2894 } 2895 /* 2896 2----3----3 2897 | | 2898 | B | 2899 | | 2900 0----4--- 1 2901 | | 2902 | A | 2903 | | 2904 0----2----1 2905 */ 2906 /* Hybrid cells have 4 faces */ 2907 for (c = cMax; c < cEnd; ++c) { 2908 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2909 const PetscInt *cone, *ornt; 2910 PetscInt coneNew[4], orntNew[4], r; 2911 2912 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2913 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2914 r = (ornt[0] < 0 ? 1 : 0); 2915 /* A quad */ 2916 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2917 orntNew[0] = ornt[0]; 2918 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2919 orntNew[1] = ornt[1]; 2920 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2921 orntNew[2+r] = 0; 2922 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2923 orntNew[3-r] = 0; 2924 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2925 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2926 #if defined(PETSC_USE_DEBUG) 2927 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); 2928 for (p = 0; p < 4; ++p) { 2929 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); 2930 } 2931 #endif 2932 /* B quad */ 2933 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2934 orntNew[0] = ornt[0]; 2935 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2936 orntNew[1] = ornt[1]; 2937 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2938 orntNew[2+r] = 0; 2939 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2940 orntNew[3-r] = 0; 2941 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2942 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2943 #if defined(PETSC_USE_DEBUG) 2944 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); 2945 for (p = 0; p < 4; ++p) { 2946 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); 2947 } 2948 #endif 2949 } 2950 /* Interior split faces have 2 vertices and the same cells as the parent */ 2951 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2952 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2953 for (f = fStart; f < fMax; ++f) { 2954 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2955 2956 for (r = 0; r < 2; ++r) { 2957 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2958 const PetscInt *cone, *ornt, *support; 2959 PetscInt coneNew[2], coneSize, c, supportSize, s; 2960 2961 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2962 coneNew[0] = vStartNew + (cone[0] - vStart); 2963 coneNew[1] = vStartNew + (cone[1] - vStart); 2964 coneNew[(r+1)%2] = newv; 2965 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2966 #if defined(PETSC_USE_DEBUG) 2967 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2968 for (p = 0; p < 2; ++p) { 2969 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); 2970 } 2971 #endif 2972 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2973 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2974 for (s = 0; s < supportSize; ++s) { 2975 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2976 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2977 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2978 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2979 if (support[s] >= cMax) { 2980 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2981 } else { 2982 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2983 } 2984 } 2985 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2986 #if defined(PETSC_USE_DEBUG) 2987 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2988 for (p = 0; p < supportSize; ++p) { 2989 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); 2990 } 2991 #endif 2992 } 2993 } 2994 /* Interior cell faces have 2 vertices and 2 cells */ 2995 for (c = cStart; c < cMax; ++c) { 2996 const PetscInt *cone; 2997 2998 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2999 for (r = 0; r < 3; ++r) { 3000 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 3001 PetscInt coneNew[2]; 3002 PetscInt supportNew[2]; 3003 3004 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3005 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 3006 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3007 #if defined(PETSC_USE_DEBUG) 3008 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3009 for (p = 0; p < 2; ++p) { 3010 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); 3011 } 3012 #endif 3013 supportNew[0] = (c - cStart)*4 + (r+1)%3; 3014 supportNew[1] = (c - cStart)*4 + 3; 3015 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3016 #if defined(PETSC_USE_DEBUG) 3017 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3018 for (p = 0; p < 2; ++p) { 3019 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); 3020 } 3021 #endif 3022 } 3023 } 3024 /* Interior hybrid faces have 2 vertices and the same cells */ 3025 for (f = fMax; f < fEnd; ++f) { 3026 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 3027 const PetscInt *cone, *ornt; 3028 const PetscInt *support; 3029 PetscInt coneNew[2]; 3030 PetscInt supportNew[2]; 3031 PetscInt size, s, r; 3032 3033 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3034 coneNew[0] = vStartNew + (cone[0] - vStart); 3035 coneNew[1] = vStartNew + (cone[1] - vStart); 3036 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3037 #if defined(PETSC_USE_DEBUG) 3038 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3039 for (p = 0; p < 2; ++p) { 3040 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); 3041 } 3042 #endif 3043 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3044 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3045 for (s = 0; s < size; ++s) { 3046 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3047 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3048 for (r = 0; r < 2; ++r) { 3049 if (cone[r+2] == f) break; 3050 } 3051 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 3052 } 3053 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3054 #if defined(PETSC_USE_DEBUG) 3055 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3056 for (p = 0; p < size; ++p) { 3057 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); 3058 } 3059 #endif 3060 } 3061 /* Cell hybrid faces have 2 vertices and 2 cells */ 3062 for (c = cMax; c < cEnd; ++c) { 3063 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 3064 const PetscInt *cone; 3065 PetscInt coneNew[2]; 3066 PetscInt supportNew[2]; 3067 3068 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3069 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3070 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3071 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3072 #if defined(PETSC_USE_DEBUG) 3073 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3074 for (p = 0; p < 2; ++p) { 3075 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); 3076 } 3077 #endif 3078 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3079 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3080 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3081 #if defined(PETSC_USE_DEBUG) 3082 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3083 for (p = 0; p < 2; ++p) { 3084 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); 3085 } 3086 #endif 3087 } 3088 /* Old vertices have identical supports */ 3089 for (v = vStart; v < vEnd; ++v) { 3090 const PetscInt newp = vStartNew + (v - vStart); 3091 const PetscInt *support, *cone; 3092 PetscInt size, s; 3093 3094 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3095 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3096 for (s = 0; s < size; ++s) { 3097 if (support[s] >= fMax) { 3098 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 3099 } else { 3100 PetscInt r = 0; 3101 3102 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3103 if (cone[1] == v) r = 1; 3104 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3105 } 3106 } 3107 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3108 #if defined(PETSC_USE_DEBUG) 3109 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3110 for (p = 0; p < size; ++p) { 3111 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); 3112 } 3113 #endif 3114 } 3115 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 3116 for (f = fStart; f < fMax; ++f) { 3117 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3118 const PetscInt *cone, *support; 3119 PetscInt size, newSize = 2, s; 3120 3121 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3122 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3123 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3124 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3125 for (s = 0; s < size; ++s) { 3126 PetscInt r = 0; 3127 3128 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3129 if (support[s] >= cMax) { 3130 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 3131 3132 newSize += 1; 3133 } else { 3134 if (cone[1] == f) r = 1; 3135 else if (cone[2] == f) r = 2; 3136 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 3137 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 3138 3139 newSize += 2; 3140 } 3141 } 3142 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3143 #if defined(PETSC_USE_DEBUG) 3144 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3145 for (p = 0; p < newSize; ++p) { 3146 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); 3147 } 3148 #endif 3149 } 3150 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3151 break; 3152 case REFINER_HYBRID_HEX_2D: 3153 /* Hybrid Hex 2D */ 3154 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 3155 cMax = PetscMin(cEnd, cMax); 3156 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 3157 fMax = PetscMin(fEnd, fMax); 3158 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 3159 /* Interior cells have 4 faces */ 3160 for (c = cStart; c < cMax; ++c) { 3161 const PetscInt newp = cStartNew + (c - cStart)*4; 3162 const PetscInt *cone, *ornt; 3163 PetscInt coneNew[4], orntNew[4]; 3164 3165 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3166 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3167 /* A quad */ 3168 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3169 orntNew[0] = ornt[0]; 3170 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3171 orntNew[1] = 0; 3172 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3173 orntNew[2] = -2; 3174 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 3175 orntNew[3] = ornt[3]; 3176 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3177 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3178 #if defined(PETSC_USE_DEBUG) 3179 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); 3180 for (p = 0; p < 4; ++p) { 3181 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); 3182 } 3183 #endif 3184 /* B quad */ 3185 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3186 orntNew[0] = ornt[0]; 3187 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3188 orntNew[1] = ornt[1]; 3189 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3190 orntNew[2] = 0; 3191 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3192 orntNew[3] = -2; 3193 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3194 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3195 #if defined(PETSC_USE_DEBUG) 3196 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); 3197 for (p = 0; p < 4; ++p) { 3198 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); 3199 } 3200 #endif 3201 /* C quad */ 3202 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3203 orntNew[0] = -2; 3204 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3205 orntNew[1] = ornt[1]; 3206 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 3207 orntNew[2] = ornt[2]; 3208 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3209 orntNew[3] = 0; 3210 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3211 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3212 #if defined(PETSC_USE_DEBUG) 3213 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); 3214 for (p = 0; p < 4; ++p) { 3215 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); 3216 } 3217 #endif 3218 /* D quad */ 3219 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3220 orntNew[0] = 0; 3221 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3222 orntNew[1] = -2; 3223 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 3224 orntNew[2] = ornt[2]; 3225 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 3226 orntNew[3] = ornt[3]; 3227 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3228 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3229 #if defined(PETSC_USE_DEBUG) 3230 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); 3231 for (p = 0; p < 4; ++p) { 3232 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); 3233 } 3234 #endif 3235 } 3236 /* 3237 2----3----3 3238 | | 3239 | B | 3240 | | 3241 0----4--- 1 3242 | | 3243 | A | 3244 | | 3245 0----2----1 3246 */ 3247 /* Hybrid cells have 4 faces */ 3248 for (c = cMax; c < cEnd; ++c) { 3249 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 3250 const PetscInt *cone, *ornt; 3251 PetscInt coneNew[4], orntNew[4]; 3252 3253 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3254 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3255 /* A quad */ 3256 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3257 orntNew[0] = ornt[0]; 3258 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3259 orntNew[1] = ornt[1]; 3260 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 3261 orntNew[2] = 0; 3262 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3263 orntNew[3] = 0; 3264 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3265 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3266 #if defined(PETSC_USE_DEBUG) 3267 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); 3268 for (p = 0; p < 4; ++p) { 3269 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); 3270 } 3271 #endif 3272 /* B quad */ 3273 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3274 orntNew[0] = ornt[0]; 3275 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3276 orntNew[1] = ornt[1]; 3277 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3278 orntNew[2] = 0; 3279 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 3280 orntNew[3] = 0; 3281 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3282 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3283 #if defined(PETSC_USE_DEBUG) 3284 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); 3285 for (p = 0; p < 4; ++p) { 3286 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); 3287 } 3288 #endif 3289 } 3290 /* Interior split faces have 2 vertices and the same cells as the parent */ 3291 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3292 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3293 for (f = fStart; f < fMax; ++f) { 3294 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 3295 3296 for (r = 0; r < 2; ++r) { 3297 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 3298 const PetscInt *cone, *ornt, *support; 3299 PetscInt coneNew[2], coneSize, c, supportSize, s; 3300 3301 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3302 coneNew[0] = vStartNew + (cone[0] - vStart); 3303 coneNew[1] = vStartNew + (cone[1] - vStart); 3304 coneNew[(r+1)%2] = newv; 3305 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3306 #if defined(PETSC_USE_DEBUG) 3307 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3308 for (p = 0; p < 2; ++p) { 3309 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); 3310 } 3311 #endif 3312 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3313 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3314 for (s = 0; s < supportSize; ++s) { 3315 if (support[s] >= cMax) { 3316 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3317 } else { 3318 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3319 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3320 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3321 for (c = 0; c < coneSize; ++c) { 3322 if (cone[c] == f) break; 3323 } 3324 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3325 } 3326 } 3327 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3328 #if defined(PETSC_USE_DEBUG) 3329 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3330 for (p = 0; p < supportSize; ++p) { 3331 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); 3332 } 3333 #endif 3334 } 3335 } 3336 /* Interior cell faces have 2 vertices and 2 cells */ 3337 for (c = cStart; c < cMax; ++c) { 3338 const PetscInt *cone; 3339 3340 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3341 for (r = 0; r < 4; ++r) { 3342 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3343 PetscInt coneNew[2], supportNew[2]; 3344 3345 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3346 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3347 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3348 #if defined(PETSC_USE_DEBUG) 3349 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3350 for (p = 0; p < 2; ++p) { 3351 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); 3352 } 3353 #endif 3354 supportNew[0] = (c - cStart)*4 + r; 3355 supportNew[1] = (c - cStart)*4 + (r+1)%4; 3356 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3357 #if defined(PETSC_USE_DEBUG) 3358 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3359 for (p = 0; p < 2; ++p) { 3360 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); 3361 } 3362 #endif 3363 } 3364 } 3365 /* Hybrid faces have 2 vertices and the same cells */ 3366 for (f = fMax; f < fEnd; ++f) { 3367 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 3368 const PetscInt *cone, *support; 3369 PetscInt coneNew[2], supportNew[2]; 3370 PetscInt size, s, r; 3371 3372 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3373 coneNew[0] = vStartNew + (cone[0] - vStart); 3374 coneNew[1] = vStartNew + (cone[1] - vStart); 3375 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3376 #if defined(PETSC_USE_DEBUG) 3377 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3378 for (p = 0; p < 2; ++p) { 3379 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); 3380 } 3381 #endif 3382 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3383 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3384 for (s = 0; s < size; ++s) { 3385 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3386 for (r = 0; r < 2; ++r) { 3387 if (cone[r+2] == f) break; 3388 } 3389 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3390 } 3391 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3392 #if defined(PETSC_USE_DEBUG) 3393 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3394 for (p = 0; p < size; ++p) { 3395 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); 3396 } 3397 #endif 3398 } 3399 /* Cell hybrid faces have 2 vertices and 2 cells */ 3400 for (c = cMax; c < cEnd; ++c) { 3401 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3402 const PetscInt *cone; 3403 PetscInt coneNew[2], supportNew[2]; 3404 3405 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3406 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3407 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3408 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3409 #if defined(PETSC_USE_DEBUG) 3410 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3411 for (p = 0; p < 2; ++p) { 3412 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); 3413 } 3414 #endif 3415 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3416 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3417 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3418 #if defined(PETSC_USE_DEBUG) 3419 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3420 for (p = 0; p < 2; ++p) { 3421 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); 3422 } 3423 #endif 3424 } 3425 /* Old vertices have identical supports */ 3426 for (v = vStart; v < vEnd; ++v) { 3427 const PetscInt newp = vStartNew + (v - vStart); 3428 const PetscInt *support, *cone; 3429 PetscInt size, s; 3430 3431 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3432 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3433 for (s = 0; s < size; ++s) { 3434 if (support[s] >= fMax) { 3435 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 3436 } else { 3437 PetscInt r = 0; 3438 3439 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3440 if (cone[1] == v) r = 1; 3441 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3442 } 3443 } 3444 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3445 #if defined(PETSC_USE_DEBUG) 3446 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3447 for (p = 0; p < size; ++p) { 3448 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); 3449 } 3450 #endif 3451 } 3452 /* Face vertices have 2 + cells supports */ 3453 for (f = fStart; f < fMax; ++f) { 3454 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3455 const PetscInt *cone, *support; 3456 PetscInt size, s; 3457 3458 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3459 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3460 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3461 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3462 for (s = 0; s < size; ++s) { 3463 PetscInt r = 0; 3464 3465 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3466 if (support[s] >= cMax) { 3467 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 3468 } else { 3469 if (cone[1] == f) r = 1; 3470 else if (cone[2] == f) r = 2; 3471 else if (cone[3] == f) r = 3; 3472 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 3473 } 3474 } 3475 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3476 #if defined(PETSC_USE_DEBUG) 3477 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3478 for (p = 0; p < 2+size; ++p) { 3479 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); 3480 } 3481 #endif 3482 } 3483 /* Cell vertices have 4 supports */ 3484 for (c = cStart; c < cMax; ++c) { 3485 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3486 PetscInt supportNew[4]; 3487 3488 for (r = 0; r < 4; ++r) { 3489 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3490 } 3491 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3492 } 3493 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3494 break; 3495 case REFINER_SIMPLEX_3D: 3496 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3497 ierr = DMPlexGetRawFaces_Internal(dm, DM_POLYTOPE_TETRAHEDRON, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3498 for (c = cStart; c < cEnd; ++c) { 3499 const PetscInt newp = cStartNew + (c - cStart)*8; 3500 const PetscInt *cone, *ornt; 3501 PetscInt coneNew[4], orntNew[4]; 3502 3503 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3504 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3505 /* A tetrahedron: {0, a, c, d} */ 3506 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3507 orntNew[0] = ornt[0]; 3508 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3509 orntNew[1] = ornt[1]; 3510 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3511 orntNew[2] = ornt[2]; 3512 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3513 orntNew[3] = 0; 3514 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3515 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3516 #if defined(PETSC_USE_DEBUG) 3517 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); 3518 for (p = 0; p < 4; ++p) { 3519 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); 3520 } 3521 #endif 3522 /* B tetrahedron: {a, 1, b, e} */ 3523 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3524 orntNew[0] = ornt[0]; 3525 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3526 orntNew[1] = ornt[1]; 3527 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3528 orntNew[2] = 0; 3529 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3530 orntNew[3] = ornt[3]; 3531 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3532 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3533 #if defined(PETSC_USE_DEBUG) 3534 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); 3535 for (p = 0; p < 4; ++p) { 3536 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); 3537 } 3538 #endif 3539 /* C tetrahedron: {c, b, 2, f} */ 3540 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3541 orntNew[0] = ornt[0]; 3542 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3543 orntNew[1] = 0; 3544 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3545 orntNew[2] = ornt[2]; 3546 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3547 orntNew[3] = ornt[3]; 3548 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3549 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3550 #if defined(PETSC_USE_DEBUG) 3551 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); 3552 for (p = 0; p < 4; ++p) { 3553 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); 3554 } 3555 #endif 3556 /* D tetrahedron: {d, e, f, 3} */ 3557 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3558 orntNew[0] = 0; 3559 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3560 orntNew[1] = ornt[1]; 3561 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3562 orntNew[2] = ornt[2]; 3563 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3564 orntNew[3] = ornt[3]; 3565 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3566 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3567 #if defined(PETSC_USE_DEBUG) 3568 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); 3569 for (p = 0; p < 4; ++p) { 3570 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); 3571 } 3572 #endif 3573 /* A' tetrahedron: {c, d, a, f} */ 3574 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3575 orntNew[0] = -3; 3576 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3577 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3578 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3579 orntNew[2] = 0; 3580 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3581 orntNew[3] = 2; 3582 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3583 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3584 #if defined(PETSC_USE_DEBUG) 3585 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); 3586 for (p = 0; p < 4; ++p) { 3587 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); 3588 } 3589 #endif 3590 /* B' tetrahedron: {e, b, a, f} */ 3591 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3592 orntNew[0] = -2; 3593 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 3594 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 3595 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3596 orntNew[2] = 0; 3597 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3598 orntNew[3] = 0; 3599 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3600 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3601 #if defined(PETSC_USE_DEBUG) 3602 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); 3603 for (p = 0; p < 4; ++p) { 3604 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); 3605 } 3606 #endif 3607 /* C' tetrahedron: {f, a, c, b} */ 3608 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3609 orntNew[0] = -2; 3610 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3611 orntNew[1] = -2; 3612 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3613 orntNew[2] = -1; 3614 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 3615 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3616 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3617 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3618 #if defined(PETSC_USE_DEBUG) 3619 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); 3620 for (p = 0; p < 4; ++p) { 3621 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); 3622 } 3623 #endif 3624 /* D' tetrahedron: {f, a, e, d} */ 3625 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3626 orntNew[0] = -2; 3627 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3628 orntNew[1] = -1; 3629 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3630 orntNew[2] = -2; 3631 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 3632 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 3633 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3634 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3635 #if defined(PETSC_USE_DEBUG) 3636 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); 3637 for (p = 0; p < 4; ++p) { 3638 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); 3639 } 3640 #endif 3641 } 3642 /* Split faces have 3 edges and the same cells as the parent */ 3643 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3644 ierr = PetscMalloc1(2 + maxSupportSize*3, &supportRef);CHKERRQ(ierr); 3645 for (f = fStart; f < fEnd; ++f) { 3646 const PetscInt newp = fStartNew + (f - fStart)*4; 3647 const PetscInt *cone, *ornt, *support; 3648 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3649 3650 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3651 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3652 /* A triangle */ 3653 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3654 orntNew[0] = ornt[0]; 3655 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3656 orntNew[1] = -2; 3657 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3658 orntNew[2] = ornt[2]; 3659 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3660 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3661 #if defined(PETSC_USE_DEBUG) 3662 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); 3663 for (p = 0; p < 3; ++p) { 3664 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); 3665 } 3666 #endif 3667 /* B triangle */ 3668 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3669 orntNew[0] = ornt[0]; 3670 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3671 orntNew[1] = ornt[1]; 3672 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3673 orntNew[2] = -2; 3674 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3675 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3676 #if defined(PETSC_USE_DEBUG) 3677 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); 3678 for (p = 0; p < 3; ++p) { 3679 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); 3680 } 3681 #endif 3682 /* C triangle */ 3683 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3684 orntNew[0] = -2; 3685 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3686 orntNew[1] = ornt[1]; 3687 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3688 orntNew[2] = ornt[2]; 3689 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3690 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3691 #if defined(PETSC_USE_DEBUG) 3692 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); 3693 for (p = 0; p < 3; ++p) { 3694 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); 3695 } 3696 #endif 3697 /* D triangle */ 3698 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3699 orntNew[0] = 0; 3700 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3701 orntNew[1] = 0; 3702 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3703 orntNew[2] = 0; 3704 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3705 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3706 #if defined(PETSC_USE_DEBUG) 3707 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); 3708 for (p = 0; p < 3; ++p) { 3709 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); 3710 } 3711 #endif 3712 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3713 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3714 for (r = 0; r < 4; ++r) { 3715 for (s = 0; s < supportSize; ++s) { 3716 PetscInt subf; 3717 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3718 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3719 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3720 for (c = 0; c < coneSize; ++c) { 3721 if (cone[c] == f) break; 3722 } 3723 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3724 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3725 } 3726 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3727 #if defined(PETSC_USE_DEBUG) 3728 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); 3729 for (p = 0; p < supportSize; ++p) { 3730 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); 3731 } 3732 #endif 3733 } 3734 } 3735 /* Interior faces have 3 edges and 2 cells */ 3736 for (c = cStart; c < cEnd; ++c) { 3737 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 3738 const PetscInt *cone, *ornt; 3739 PetscInt coneNew[3], orntNew[3]; 3740 PetscInt supportNew[2]; 3741 3742 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3743 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3744 /* Face A: {c, a, d} */ 3745 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3746 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3747 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3748 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3749 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3750 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3751 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3752 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3753 #if defined(PETSC_USE_DEBUG) 3754 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3755 for (p = 0; p < 3; ++p) { 3756 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); 3757 } 3758 #endif 3759 supportNew[0] = (c - cStart)*8 + 0; 3760 supportNew[1] = (c - cStart)*8 + 0+4; 3761 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3762 #if defined(PETSC_USE_DEBUG) 3763 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3764 for (p = 0; p < 2; ++p) { 3765 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); 3766 } 3767 #endif 3768 ++newp; 3769 /* Face B: {a, b, e} */ 3770 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3771 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3772 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3773 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3774 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3775 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3776 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3777 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3778 #if defined(PETSC_USE_DEBUG) 3779 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3780 for (p = 0; p < 3; ++p) { 3781 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); 3782 } 3783 #endif 3784 supportNew[0] = (c - cStart)*8 + 1; 3785 supportNew[1] = (c - cStart)*8 + 1+4; 3786 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3787 #if defined(PETSC_USE_DEBUG) 3788 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3789 for (p = 0; p < 2; ++p) { 3790 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); 3791 } 3792 #endif 3793 ++newp; 3794 /* Face C: {c, f, b} */ 3795 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3796 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3797 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3798 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3799 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3800 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3801 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3802 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3803 #if defined(PETSC_USE_DEBUG) 3804 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3805 for (p = 0; p < 3; ++p) { 3806 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); 3807 } 3808 #endif 3809 supportNew[0] = (c - cStart)*8 + 2; 3810 supportNew[1] = (c - cStart)*8 + 2+4; 3811 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3812 #if defined(PETSC_USE_DEBUG) 3813 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3814 for (p = 0; p < 2; ++p) { 3815 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); 3816 } 3817 #endif 3818 ++newp; 3819 /* Face D: {d, e, f} */ 3820 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3821 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3822 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3823 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3824 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3825 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3826 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3827 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3828 #if defined(PETSC_USE_DEBUG) 3829 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3830 for (p = 0; p < 3; ++p) { 3831 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); 3832 } 3833 #endif 3834 supportNew[0] = (c - cStart)*8 + 3; 3835 supportNew[1] = (c - cStart)*8 + 3+4; 3836 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3837 #if defined(PETSC_USE_DEBUG) 3838 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3839 for (p = 0; p < 2; ++p) { 3840 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); 3841 } 3842 #endif 3843 ++newp; 3844 /* Face E: {d, f, a} */ 3845 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3846 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3847 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3848 orntNew[1] = -2; 3849 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3850 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3851 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3852 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3853 #if defined(PETSC_USE_DEBUG) 3854 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3855 for (p = 0; p < 3; ++p) { 3856 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); 3857 } 3858 #endif 3859 supportNew[0] = (c - cStart)*8 + 0+4; 3860 supportNew[1] = (c - cStart)*8 + 3+4; 3861 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3862 #if defined(PETSC_USE_DEBUG) 3863 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3864 for (p = 0; p < 2; ++p) { 3865 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); 3866 } 3867 #endif 3868 ++newp; 3869 /* Face F: {c, a, f} */ 3870 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3871 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3872 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3873 orntNew[1] = 0; 3874 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3875 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3876 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3877 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3878 #if defined(PETSC_USE_DEBUG) 3879 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3880 for (p = 0; p < 3; ++p) { 3881 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); 3882 } 3883 #endif 3884 supportNew[0] = (c - cStart)*8 + 0+4; 3885 supportNew[1] = (c - cStart)*8 + 2+4; 3886 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3887 #if defined(PETSC_USE_DEBUG) 3888 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3889 for (p = 0; p < 2; ++p) { 3890 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); 3891 } 3892 #endif 3893 ++newp; 3894 /* Face G: {e, a, f} */ 3895 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3896 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3897 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3898 orntNew[1] = 0; 3899 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3900 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3901 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3902 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3903 #if defined(PETSC_USE_DEBUG) 3904 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3905 for (p = 0; p < 3; ++p) { 3906 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); 3907 } 3908 #endif 3909 supportNew[0] = (c - cStart)*8 + 1+4; 3910 supportNew[1] = (c - cStart)*8 + 3+4; 3911 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3912 #if defined(PETSC_USE_DEBUG) 3913 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3914 for (p = 0; p < 2; ++p) { 3915 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); 3916 } 3917 #endif 3918 ++newp; 3919 /* Face H: {a, b, f} */ 3920 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3921 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3922 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3923 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3924 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3925 orntNew[2] = -2; 3926 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3927 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3928 #if defined(PETSC_USE_DEBUG) 3929 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3930 for (p = 0; p < 3; ++p) { 3931 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); 3932 } 3933 #endif 3934 supportNew[0] = (c - cStart)*8 + 1+4; 3935 supportNew[1] = (c - cStart)*8 + 2+4; 3936 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3937 #if defined(PETSC_USE_DEBUG) 3938 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3939 for (p = 0; p < 2; ++p) { 3940 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); 3941 } 3942 #endif 3943 ++newp; 3944 } 3945 /* Split Edges have 2 vertices and the same faces as the parent */ 3946 for (e = eStart; e < eEnd; ++e) { 3947 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3948 3949 for (r = 0; r < 2; ++r) { 3950 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3951 const PetscInt *cone, *ornt, *support; 3952 PetscInt coneNew[2], coneSize, c, supportSize, s; 3953 3954 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3955 coneNew[0] = vStartNew + (cone[0] - vStart); 3956 coneNew[1] = vStartNew + (cone[1] - vStart); 3957 coneNew[(r+1)%2] = newv; 3958 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3959 #if defined(PETSC_USE_DEBUG) 3960 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3961 for (p = 0; p < 2; ++p) { 3962 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); 3963 } 3964 #endif 3965 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3966 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3967 for (s = 0; s < supportSize; ++s) { 3968 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3969 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3970 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3971 for (c = 0; c < coneSize; ++c) { 3972 if (cone[c] == e) break; 3973 } 3974 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3975 } 3976 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3977 #if defined(PETSC_USE_DEBUG) 3978 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3979 for (p = 0; p < supportSize; ++p) { 3980 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); 3981 } 3982 #endif 3983 } 3984 } 3985 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3986 for (f = fStart; f < fEnd; ++f) { 3987 const PetscInt *cone, *ornt, *support; 3988 PetscInt coneSize, supportSize, s; 3989 3990 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3991 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3992 for (r = 0; r < 3; ++r) { 3993 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3994 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3995 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3996 -1, -1, 1, 6, 0, 4, 3997 2, 5, 3, 4, -1, -1, 3998 -1, -1, 3, 6, 2, 7}; 3999 4000 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4001 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4002 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4003 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4004 #if defined(PETSC_USE_DEBUG) 4005 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4006 for (p = 0; p < 2; ++p) { 4007 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); 4008 } 4009 #endif 4010 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4011 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4012 for (s = 0; s < supportSize; ++s) { 4013 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4014 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4015 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4016 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4017 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4018 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4019 if (er == eint[c]) { 4020 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4021 } else { 4022 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4023 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4024 } 4025 } 4026 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4027 #if defined(PETSC_USE_DEBUG) 4028 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4029 for (p = 0; p < intFaces; ++p) { 4030 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); 4031 } 4032 #endif 4033 } 4034 } 4035 /* Interior edges have 2 vertices and 4 faces */ 4036 for (c = cStart; c < cEnd; ++c) { 4037 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 4038 const PetscInt *cone, *ornt, *fcone; 4039 PetscInt coneNew[2], supportNew[4], find; 4040 4041 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4042 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4043 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4044 find = GetTriEdge_Static(ornt[0], 0); 4045 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4046 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4047 find = GetTriEdge_Static(ornt[2], 1); 4048 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4049 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4050 #if defined(PETSC_USE_DEBUG) 4051 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4052 for (p = 0; p < 2; ++p) { 4053 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); 4054 } 4055 #endif 4056 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 4057 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 4058 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 4059 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 4060 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4061 #if defined(PETSC_USE_DEBUG) 4062 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4063 for (p = 0; p < 4; ++p) { 4064 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); 4065 } 4066 #endif 4067 } 4068 /* Old vertices have identical supports */ 4069 for (v = vStart; v < vEnd; ++v) { 4070 const PetscInt newp = vStartNew + (v - vStart); 4071 const PetscInt *support, *cone; 4072 PetscInt size, s; 4073 4074 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4075 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4076 for (s = 0; s < size; ++s) { 4077 PetscInt r = 0; 4078 4079 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4080 if (cone[1] == v) r = 1; 4081 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4082 } 4083 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4084 #if defined(PETSC_USE_DEBUG) 4085 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4086 for (p = 0; p < size; ++p) { 4087 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); 4088 } 4089 #endif 4090 } 4091 /* Edge vertices have 2 + face*2 + 0/1 supports */ 4092 for (e = eStart; e < eEnd; ++e) { 4093 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4094 const PetscInt *cone, *support; 4095 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 4096 4097 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4098 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4099 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4100 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4101 for (s = 0; s < size; ++s) { 4102 PetscInt r = 0; 4103 4104 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4105 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4106 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4107 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4108 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4109 } 4110 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4111 for (s = 0; s < starSize*2; s += 2) { 4112 const PetscInt *cone, *ornt; 4113 PetscInt e01, e23; 4114 4115 if ((star[s] >= cStart) && (star[s] < cEnd)) { 4116 /* Check edge 0-1 */ 4117 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4118 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4119 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4120 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4121 /* Check edge 2-3 */ 4122 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4123 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4124 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4125 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4126 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 4127 } 4128 } 4129 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4130 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4131 #if defined(PETSC_USE_DEBUG) 4132 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4133 for (p = 0; p < 2+size*2+cellSize; ++p) { 4134 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); 4135 } 4136 #endif 4137 } 4138 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4139 ierr = DMPlexRestoreFaces_Internal(dm, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4140 break; 4141 case REFINER_HYBRID_SIMPLEX_3D: 4142 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4143 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 4144 ierr = DMPlexGetRawFaces_Internal(dm, DM_POLYTOPE_TETRAHEDRON, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4145 for (c = cStart; c < cMax; ++c) { 4146 const PetscInt newp = cStartNew + (c - cStart)*8; 4147 const PetscInt *cone, *ornt; 4148 PetscInt coneNew[4], orntNew[4]; 4149 4150 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4151 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4152 /* A tetrahedron: {0, a, c, d} */ 4153 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 4154 orntNew[0] = ornt[0]; 4155 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 4156 orntNew[1] = ornt[1]; 4157 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 4158 orntNew[2] = ornt[2]; 4159 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4160 orntNew[3] = 0; 4161 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4162 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4163 #if defined(PETSC_USE_DEBUG) 4164 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); 4165 for (p = 0; p < 4; ++p) { 4166 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); 4167 } 4168 #endif 4169 /* B tetrahedron: {a, 1, b, e} */ 4170 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 4171 orntNew[0] = ornt[0]; 4172 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 4173 orntNew[1] = ornt[1]; 4174 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4175 orntNew[2] = 0; 4176 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 4177 orntNew[3] = ornt[3]; 4178 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4179 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4180 #if defined(PETSC_USE_DEBUG) 4181 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); 4182 for (p = 0; p < 4; ++p) { 4183 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); 4184 } 4185 #endif 4186 /* C tetrahedron: {c, b, 2, f} */ 4187 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 4188 orntNew[0] = ornt[0]; 4189 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4190 orntNew[1] = 0; 4191 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 4192 orntNew[2] = ornt[2]; 4193 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 4194 orntNew[3] = ornt[3]; 4195 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4196 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4197 #if defined(PETSC_USE_DEBUG) 4198 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); 4199 for (p = 0; p < 4; ++p) { 4200 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); 4201 } 4202 #endif 4203 /* D tetrahedron: {d, e, f, 3} */ 4204 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4205 orntNew[0] = 0; 4206 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 4207 orntNew[1] = ornt[1]; 4208 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 4209 orntNew[2] = ornt[2]; 4210 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 4211 orntNew[3] = ornt[3]; 4212 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4213 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4214 #if defined(PETSC_USE_DEBUG) 4215 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); 4216 for (p = 0; p < 4; ++p) { 4217 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); 4218 } 4219 #endif 4220 /* A' tetrahedron: {d, a, c, f} */ 4221 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4222 orntNew[0] = -3; 4223 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 4224 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 4225 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4226 orntNew[2] = 0; 4227 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4228 orntNew[3] = 2; 4229 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4230 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4231 #if defined(PETSC_USE_DEBUG) 4232 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); 4233 for (p = 0; p < 4; ++p) { 4234 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); 4235 } 4236 #endif 4237 /* B' tetrahedron: {e, b, a, f} */ 4238 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4239 orntNew[0] = -3; 4240 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4241 orntNew[1] = 1; 4242 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4243 orntNew[2] = 0; 4244 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 4245 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 4246 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4247 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4248 #if defined(PETSC_USE_DEBUG) 4249 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); 4250 for (p = 0; p < 4; ++p) { 4251 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); 4252 } 4253 #endif 4254 /* C' tetrahedron: {b, f, c, a} */ 4255 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4256 orntNew[0] = -3; 4257 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 4258 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 4259 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4260 orntNew[2] = -3; 4261 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4262 orntNew[3] = -2; 4263 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4264 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4265 #if defined(PETSC_USE_DEBUG) 4266 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); 4267 for (p = 0; p < 4; ++p) { 4268 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); 4269 } 4270 #endif 4271 /* D' tetrahedron: {f, e, d, a} */ 4272 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4273 orntNew[0] = -3; 4274 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4275 orntNew[1] = -3; 4276 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 4277 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 4278 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4279 orntNew[3] = -3; 4280 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4281 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4282 #if defined(PETSC_USE_DEBUG) 4283 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); 4284 for (p = 0; p < 4; ++p) { 4285 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); 4286 } 4287 #endif 4288 } 4289 /* Hybrid cells have 5 faces */ 4290 for (c = cMax; c < cEnd; ++c) { 4291 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 4292 const PetscInt *cone, *ornt, *fornt; 4293 PetscInt coneNew[5], orntNew[5], o, of, i; 4294 4295 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4296 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4297 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4298 o = ornt[0] < 0 ? -1 : 1; 4299 for (r = 0; r < 3; ++r) { 4300 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 4301 orntNew[0] = ornt[0]; 4302 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 4303 orntNew[1] = ornt[1]; 4304 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 4305 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 4306 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 4307 orntNew[i] = 0; 4308 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 4309 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 4310 orntNew[i] = 0; 4311 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 4312 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 4313 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); 4314 orntNew[i] = 0; 4315 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4316 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4317 #if defined(PETSC_USE_DEBUG) 4318 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); 4319 for (p = 0; p < 2; ++p) { 4320 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); 4321 } 4322 for (p = 2; p < 5; ++p) { 4323 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); 4324 } 4325 #endif 4326 } 4327 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 4328 orntNew[0] = 0; 4329 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 4330 orntNew[1] = 0; 4331 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 4332 orntNew[2] = 0; 4333 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 4334 orntNew[3] = 0; 4335 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 4336 orntNew[4] = 0; 4337 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4338 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4339 #if defined(PETSC_USE_DEBUG) 4340 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); 4341 for (p = 0; p < 2; ++p) { 4342 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); 4343 } 4344 for (p = 2; p < 5; ++p) { 4345 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); 4346 } 4347 #endif 4348 } 4349 /* Split faces have 3 edges and the same cells as the parent */ 4350 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4351 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4352 for (f = fStart; f < fMax; ++f) { 4353 const PetscInt newp = fStartNew + (f - fStart)*4; 4354 const PetscInt *cone, *ornt, *support; 4355 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 4356 4357 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4358 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4359 /* A triangle */ 4360 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4361 orntNew[0] = ornt[0]; 4362 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4363 orntNew[1] = -2; 4364 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4365 orntNew[2] = ornt[2]; 4366 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4367 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4368 #if defined(PETSC_USE_DEBUG) 4369 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); 4370 for (p = 0; p < 3; ++p) { 4371 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); 4372 } 4373 #endif 4374 /* B triangle */ 4375 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4376 orntNew[0] = ornt[0]; 4377 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4378 orntNew[1] = ornt[1]; 4379 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4380 orntNew[2] = -2; 4381 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4382 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4383 #if defined(PETSC_USE_DEBUG) 4384 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); 4385 for (p = 0; p < 3; ++p) { 4386 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); 4387 } 4388 #endif 4389 /* C triangle */ 4390 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4391 orntNew[0] = -2; 4392 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4393 orntNew[1] = ornt[1]; 4394 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4395 orntNew[2] = ornt[2]; 4396 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4397 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4398 #if defined(PETSC_USE_DEBUG) 4399 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); 4400 for (p = 0; p < 3; ++p) { 4401 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); 4402 } 4403 #endif 4404 /* D triangle */ 4405 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4406 orntNew[0] = 0; 4407 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4408 orntNew[1] = 0; 4409 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4410 orntNew[2] = 0; 4411 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4412 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4413 #if defined(PETSC_USE_DEBUG) 4414 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); 4415 for (p = 0; p < 3; ++p) { 4416 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); 4417 } 4418 #endif 4419 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4420 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4421 for (r = 0; r < 4; ++r) { 4422 for (s = 0; s < supportSize; ++s) { 4423 PetscInt subf; 4424 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4425 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4426 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4427 for (c = 0; c < coneSize; ++c) { 4428 if (cone[c] == f) break; 4429 } 4430 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4431 if (support[s] < cMax) { 4432 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 4433 } else { 4434 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 4435 } 4436 } 4437 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4438 #if defined(PETSC_USE_DEBUG) 4439 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); 4440 for (p = 0; p < supportSize; ++p) { 4441 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); 4442 } 4443 #endif 4444 } 4445 } 4446 /* Interior cell faces have 3 edges and 2 cells */ 4447 for (c = cStart; c < cMax; ++c) { 4448 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 4449 const PetscInt *cone, *ornt; 4450 PetscInt coneNew[3], orntNew[3]; 4451 PetscInt supportNew[2]; 4452 4453 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4454 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4455 /* Face A: {c, a, d} */ 4456 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4457 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4458 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4459 orntNew[1] = ornt[1] < 0 ? -2 : 0; 4460 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 4461 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4462 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4463 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4464 #if defined(PETSC_USE_DEBUG) 4465 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4466 for (p = 0; p < 3; ++p) { 4467 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); 4468 } 4469 #endif 4470 supportNew[0] = (c - cStart)*8 + 0; 4471 supportNew[1] = (c - cStart)*8 + 0+4; 4472 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4473 #if defined(PETSC_USE_DEBUG) 4474 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4475 for (p = 0; p < 2; ++p) { 4476 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); 4477 } 4478 #endif 4479 ++newp; 4480 /* Face B: {a, b, e} */ 4481 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4482 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4483 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 4484 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4485 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4486 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4487 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4488 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4489 #if defined(PETSC_USE_DEBUG) 4490 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); 4491 for (p = 0; p < 3; ++p) { 4492 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); 4493 } 4494 #endif 4495 supportNew[0] = (c - cStart)*8 + 1; 4496 supportNew[1] = (c - cStart)*8 + 1+4; 4497 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4498 #if defined(PETSC_USE_DEBUG) 4499 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4500 for (p = 0; p < 2; ++p) { 4501 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); 4502 } 4503 #endif 4504 ++newp; 4505 /* Face C: {c, f, b} */ 4506 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4507 orntNew[0] = ornt[2] < 0 ? -2 : 0; 4508 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4509 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4510 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 4511 orntNew[2] = ornt[0] < 0 ? -2 : 0; 4512 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4513 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4514 #if defined(PETSC_USE_DEBUG) 4515 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4516 for (p = 0; p < 3; ++p) { 4517 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); 4518 } 4519 #endif 4520 supportNew[0] = (c - cStart)*8 + 2; 4521 supportNew[1] = (c - cStart)*8 + 2+4; 4522 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4523 #if defined(PETSC_USE_DEBUG) 4524 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4525 for (p = 0; p < 2; ++p) { 4526 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); 4527 } 4528 #endif 4529 ++newp; 4530 /* Face D: {d, e, f} */ 4531 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 4532 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4533 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4534 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4535 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4536 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4537 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4538 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4539 #if defined(PETSC_USE_DEBUG) 4540 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4541 for (p = 0; p < 3; ++p) { 4542 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); 4543 } 4544 #endif 4545 supportNew[0] = (c - cStart)*8 + 3; 4546 supportNew[1] = (c - cStart)*8 + 3+4; 4547 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4548 #if defined(PETSC_USE_DEBUG) 4549 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4550 for (p = 0; p < 2; ++p) { 4551 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); 4552 } 4553 #endif 4554 ++newp; 4555 /* Face E: {d, f, a} */ 4556 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4557 orntNew[0] = ornt[2] < 0 ? 0 : -2; 4558 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4559 orntNew[1] = -2; 4560 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4561 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4562 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4563 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4564 #if defined(PETSC_USE_DEBUG) 4565 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4566 for (p = 0; p < 3; ++p) { 4567 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); 4568 } 4569 #endif 4570 supportNew[0] = (c - cStart)*8 + 0+4; 4571 supportNew[1] = (c - cStart)*8 + 3+4; 4572 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4573 #if defined(PETSC_USE_DEBUG) 4574 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4575 for (p = 0; p < 2; ++p) { 4576 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); 4577 } 4578 #endif 4579 ++newp; 4580 /* Face F: {c, a, f} */ 4581 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4582 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4583 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4584 orntNew[1] = 0; 4585 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4586 orntNew[2] = ornt[2] < 0 ? 0 : -2; 4587 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4588 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4589 #if defined(PETSC_USE_DEBUG) 4590 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4591 for (p = 0; p < 3; ++p) { 4592 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); 4593 } 4594 #endif 4595 supportNew[0] = (c - cStart)*8 + 0+4; 4596 supportNew[1] = (c - cStart)*8 + 2+4; 4597 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4598 #if defined(PETSC_USE_DEBUG) 4599 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4600 for (p = 0; p < 2; ++p) { 4601 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); 4602 } 4603 #endif 4604 ++newp; 4605 /* Face G: {e, a, f} */ 4606 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4607 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4608 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4609 orntNew[1] = 0; 4610 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4611 orntNew[2] = ornt[3] < 0 ? 0 : -2; 4612 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4613 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4614 #if defined(PETSC_USE_DEBUG) 4615 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4616 for (p = 0; p < 3; ++p) { 4617 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); 4618 } 4619 #endif 4620 supportNew[0] = (c - cStart)*8 + 1+4; 4621 supportNew[1] = (c - cStart)*8 + 3+4; 4622 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4623 #if defined(PETSC_USE_DEBUG) 4624 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4625 for (p = 0; p < 2; ++p) { 4626 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); 4627 } 4628 #endif 4629 ++newp; 4630 /* Face H: {a, b, f} */ 4631 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4632 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4633 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4634 orntNew[1] = ornt[3] < 0 ? 0 : -2; 4635 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4636 orntNew[2] = -2; 4637 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4638 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4639 #if defined(PETSC_USE_DEBUG) 4640 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4641 for (p = 0; p < 3; ++p) { 4642 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); 4643 } 4644 #endif 4645 supportNew[0] = (c - cStart)*8 + 1+4; 4646 supportNew[1] = (c - cStart)*8 + 2+4; 4647 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4648 #if defined(PETSC_USE_DEBUG) 4649 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4650 for (p = 0; p < 2; ++p) { 4651 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); 4652 } 4653 #endif 4654 ++newp; 4655 } 4656 /* Hybrid split faces have 4 edges and same cells */ 4657 for (f = fMax; f < fEnd; ++f) { 4658 const PetscInt *cone, *ornt, *support; 4659 PetscInt coneNew[4], orntNew[4]; 4660 PetscInt supportNew[2], size, s, c; 4661 4662 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4663 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4664 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4665 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4666 for (r = 0; r < 2; ++r) { 4667 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 4668 4669 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4670 orntNew[0] = ornt[0]; 4671 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4672 orntNew[1] = ornt[1]; 4673 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 4674 orntNew[2+r] = 0; 4675 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4676 orntNew[3-r] = 0; 4677 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4678 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4679 #if defined(PETSC_USE_DEBUG) 4680 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4681 for (p = 0; p < 2; ++p) { 4682 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); 4683 } 4684 for (p = 2; p < 4; ++p) { 4685 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); 4686 } 4687 #endif 4688 for (s = 0; s < size; ++s) { 4689 const PetscInt *coneCell, *orntCell, *fornt; 4690 PetscInt o, of; 4691 4692 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4693 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4694 o = orntCell[0] < 0 ? -1 : 1; 4695 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 4696 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 4697 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4698 of = fornt[c-2] < 0 ? -1 : 1; 4699 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 4700 } 4701 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4702 #if defined(PETSC_USE_DEBUG) 4703 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4704 for (p = 0; p < size; ++p) { 4705 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); 4706 } 4707 #endif 4708 } 4709 } 4710 /* Hybrid cell faces have 4 edges and 2 cells */ 4711 for (c = cMax; c < cEnd; ++c) { 4712 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 4713 const PetscInt *cone, *ornt; 4714 PetscInt coneNew[4], orntNew[4]; 4715 PetscInt supportNew[2]; 4716 4717 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4718 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4719 for (r = 0; r < 3; ++r) { 4720 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 4721 orntNew[0] = 0; 4722 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 4723 orntNew[1] = 0; 4724 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 4725 orntNew[2] = 0; 4726 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 4727 orntNew[3] = 0; 4728 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4729 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4730 #if defined(PETSC_USE_DEBUG) 4731 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); 4732 for (p = 0; p < 2; ++p) { 4733 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); 4734 } 4735 for (p = 2; p < 4; ++p) { 4736 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); 4737 } 4738 #endif 4739 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 4740 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 4741 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4742 #if defined(PETSC_USE_DEBUG) 4743 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); 4744 for (p = 0; p < 2; ++p) { 4745 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); 4746 } 4747 #endif 4748 } 4749 } 4750 /* Interior split edges have 2 vertices and the same faces as the parent */ 4751 for (e = eStart; e < eMax; ++e) { 4752 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4753 4754 for (r = 0; r < 2; ++r) { 4755 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4756 const PetscInt *cone, *ornt, *support; 4757 PetscInt coneNew[2], coneSize, c, supportSize, s; 4758 4759 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4760 coneNew[0] = vStartNew + (cone[0] - vStart); 4761 coneNew[1] = vStartNew + (cone[1] - vStart); 4762 coneNew[(r+1)%2] = newv; 4763 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4764 #if defined(PETSC_USE_DEBUG) 4765 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4766 for (p = 0; p < 2; ++p) { 4767 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); 4768 } 4769 #endif 4770 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4771 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4772 for (s = 0; s < supportSize; ++s) { 4773 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4774 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4775 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4776 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 4777 if (support[s] < fMax) { 4778 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4779 } else { 4780 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4781 } 4782 } 4783 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4784 #if defined(PETSC_USE_DEBUG) 4785 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4786 for (p = 0; p < supportSize; ++p) { 4787 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); 4788 } 4789 #endif 4790 } 4791 } 4792 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 4793 for (f = fStart; f < fMax; ++f) { 4794 const PetscInt *cone, *ornt, *support; 4795 PetscInt coneSize, supportSize, s; 4796 4797 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4798 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4799 for (r = 0; r < 3; ++r) { 4800 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 4801 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 4802 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 4803 -1, -1, 1, 6, 0, 4, 4804 2, 5, 3, 4, -1, -1, 4805 -1, -1, 3, 6, 2, 7}; 4806 4807 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4808 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4809 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4810 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4811 #if defined(PETSC_USE_DEBUG) 4812 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4813 for (p = 0; p < 2; ++p) { 4814 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); 4815 } 4816 #endif 4817 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4818 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4819 for (s = 0; s < supportSize; ++s) { 4820 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4821 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4822 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4823 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4824 if (support[s] < cMax) { 4825 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4826 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4827 if (er == eint[c]) { 4828 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4829 } else { 4830 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4831 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4832 } 4833 } else { 4834 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4835 } 4836 } 4837 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4838 #if defined(PETSC_USE_DEBUG) 4839 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4840 for (p = 0; p < intFaces; ++p) { 4841 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); 4842 } 4843 #endif 4844 } 4845 } 4846 /* Interior cell edges have 2 vertices and 4 faces */ 4847 for (c = cStart; c < cMax; ++c) { 4848 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4849 const PetscInt *cone, *ornt, *fcone; 4850 PetscInt coneNew[2], supportNew[4], find; 4851 4852 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4853 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4854 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4855 find = GetTriEdge_Static(ornt[0], 0); 4856 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4857 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4858 find = GetTriEdge_Static(ornt[2], 1); 4859 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4860 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4861 #if defined(PETSC_USE_DEBUG) 4862 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4863 for (p = 0; p < 2; ++p) { 4864 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); 4865 } 4866 #endif 4867 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4868 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4869 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4870 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4871 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4872 #if defined(PETSC_USE_DEBUG) 4873 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4874 for (p = 0; p < 4; ++p) { 4875 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); 4876 } 4877 #endif 4878 } 4879 /* Hybrid edges have two vertices and the same faces */ 4880 for (e = eMax; e < eEnd; ++e) { 4881 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4882 const PetscInt *cone, *support, *fcone; 4883 PetscInt coneNew[2], size, fsize, s; 4884 4885 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4886 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4887 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4888 coneNew[0] = vStartNew + (cone[0] - vStart); 4889 coneNew[1] = vStartNew + (cone[1] - vStart); 4890 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4891 #if defined(PETSC_USE_DEBUG) 4892 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4893 for (p = 0; p < 2; ++p) { 4894 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); 4895 } 4896 #endif 4897 for (s = 0; s < size; ++s) { 4898 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4899 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4900 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4901 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 4902 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4903 } 4904 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4905 #if defined(PETSC_USE_DEBUG) 4906 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4907 for (p = 0; p < size; ++p) { 4908 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); 4909 } 4910 #endif 4911 } 4912 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4913 for (f = fMax; f < fEnd; ++f) { 4914 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4915 const PetscInt *cone, *support, *ccone, *cornt; 4916 PetscInt coneNew[2], size, csize, s; 4917 4918 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4919 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4920 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4921 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4922 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4923 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4924 #if defined(PETSC_USE_DEBUG) 4925 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4926 for (p = 0; p < 2; ++p) { 4927 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); 4928 } 4929 #endif 4930 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4931 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4932 for (s = 0; s < size; ++s) { 4933 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4934 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4935 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4936 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4937 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]); 4938 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4939 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4940 } 4941 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4942 #if defined(PETSC_USE_DEBUG) 4943 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4944 for (p = 0; p < 2+size*2; ++p) { 4945 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); 4946 } 4947 #endif 4948 } 4949 /* Interior vertices have identical supports */ 4950 for (v = vStart; v < vEnd; ++v) { 4951 const PetscInt newp = vStartNew + (v - vStart); 4952 const PetscInt *support, *cone; 4953 PetscInt size, s; 4954 4955 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4956 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4957 for (s = 0; s < size; ++s) { 4958 PetscInt r = 0; 4959 4960 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4961 if (cone[1] == v) r = 1; 4962 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4963 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4964 } 4965 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4966 #if defined(PETSC_USE_DEBUG) 4967 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4968 for (p = 0; p < size; ++p) { 4969 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); 4970 } 4971 #endif 4972 } 4973 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4974 for (e = eStart; e < eMax; ++e) { 4975 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4976 const PetscInt *cone, *support; 4977 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4978 4979 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4980 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4981 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4982 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4983 for (s = 0; s < size; ++s) { 4984 PetscInt r = 0; 4985 4986 if (support[s] < fMax) { 4987 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4988 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4989 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4990 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4991 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4992 faceSize += 2; 4993 } else { 4994 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4995 ++faceSize; 4996 } 4997 } 4998 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4999 for (s = 0; s < starSize*2; s += 2) { 5000 const PetscInt *cone, *ornt; 5001 PetscInt e01, e23; 5002 5003 if ((star[s] >= cStart) && (star[s] < cMax)) { 5004 /* Check edge 0-1 */ 5005 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 5006 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 5007 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 5008 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 5009 /* Check edge 2-3 */ 5010 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 5011 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 5012 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 5013 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 5014 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 5015 } 5016 } 5017 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 5018 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5019 #if defined(PETSC_USE_DEBUG) 5020 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5021 for (p = 0; p < 2+faceSize+cellSize; ++p) { 5022 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); 5023 } 5024 #endif 5025 } 5026 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5027 ierr = DMPlexRestoreFaces_Internal(dm, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5028 break; 5029 case REFINER_SIMPLEX_TO_HEX_3D: 5030 ierr = DMPlexGetRawFaces_Internal(dm, DM_POLYTOPE_TETRAHEDRON, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5031 /* All cells have 6 faces */ 5032 for (c = cStart; c < cEnd; ++c) { 5033 const PetscInt newp = cStartNew + (c - cStart)*4; 5034 const PetscInt *cone, *ornt; 5035 PetscInt coneNew[6]; 5036 PetscInt orntNew[6]; 5037 5038 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5039 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5040 /* A hex */ 5041 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5042 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5043 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5044 orntNew[1] = -4; 5045 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5046 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5047 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5048 orntNew[3] = -1; 5049 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5050 orntNew[4] = 0; 5051 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5052 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5053 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5054 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5055 #if defined(PETSC_USE_DEBUG) 5056 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); 5057 for (p = 0; p < 6; ++p) { 5058 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); 5059 } 5060 #endif 5061 /* B hex */ 5062 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5063 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5064 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5065 orntNew[1] = 0; 5066 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5067 orntNew[2] = 0; 5068 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5069 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5070 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5071 orntNew[4] = 0; 5072 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5073 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5074 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5075 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5076 #if defined(PETSC_USE_DEBUG) 5077 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); 5078 for (p = 0; p < 6; ++p) { 5079 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); 5080 } 5081 #endif 5082 /* C hex */ 5083 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5084 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5085 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5086 orntNew[1] = -4; 5087 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5088 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5089 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5090 orntNew[3] = -1; 5091 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5092 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5093 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5094 orntNew[5] = -4; 5095 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5096 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5097 #if defined(PETSC_USE_DEBUG) 5098 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); 5099 for (p = 0; p < 6; ++p) { 5100 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); 5101 } 5102 #endif 5103 /* D hex */ 5104 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5105 orntNew[0] = 0; 5106 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5107 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5108 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5109 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5110 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5111 orntNew[3] = -1; 5112 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5113 orntNew[4] = 0; 5114 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5115 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5116 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5117 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5118 #if defined(PETSC_USE_DEBUG) 5119 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); 5120 for (p = 0; p < 6; ++p) { 5121 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); 5122 } 5123 #endif 5124 } 5125 /* Split faces have 4 edges and the same cells as the parent */ 5126 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5127 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5128 for (f = fStart; f < fEnd; ++f) { 5129 const PetscInt newp = fStartNew + (f - fStart)*3; 5130 const PetscInt *cone, *ornt, *support; 5131 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5132 5133 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5134 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5135 /* A quad */ 5136 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5137 orntNew[0] = ornt[2]; 5138 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5139 orntNew[1] = ornt[0]; 5140 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5141 orntNew[2] = 0; 5142 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5143 orntNew[3] = -2; 5144 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5145 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5146 #if defined(PETSC_USE_DEBUG) 5147 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); 5148 for (p = 0; p < 4; ++p) { 5149 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); 5150 } 5151 #endif 5152 /* B quad */ 5153 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5154 orntNew[0] = ornt[0]; 5155 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5156 orntNew[1] = ornt[1]; 5157 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5158 orntNew[2] = 0; 5159 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5160 orntNew[3] = -2; 5161 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5162 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5163 #if defined(PETSC_USE_DEBUG) 5164 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); 5165 for (p = 0; p < 4; ++p) { 5166 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); 5167 } 5168 #endif 5169 /* C quad */ 5170 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5171 orntNew[0] = ornt[1]; 5172 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5173 orntNew[1] = ornt[2]; 5174 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5175 orntNew[2] = 0; 5176 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5177 orntNew[3] = -2; 5178 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5179 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5180 #if defined(PETSC_USE_DEBUG) 5181 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); 5182 for (p = 0; p < 4; ++p) { 5183 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); 5184 } 5185 #endif 5186 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5187 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5188 for (r = 0; r < 3; ++r) { 5189 for (s = 0; s < supportSize; ++s) { 5190 PetscInt subf; 5191 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5192 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5193 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5194 for (c = 0; c < coneSize; ++c) { 5195 if (cone[c] == f) break; 5196 } 5197 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5198 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5199 } 5200 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5201 #if defined(PETSC_USE_DEBUG) 5202 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); 5203 for (p = 0; p < supportSize; ++p) { 5204 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); 5205 } 5206 #endif 5207 } 5208 } 5209 /* Interior faces have 4 edges and 2 cells */ 5210 for (c = cStart; c < cEnd; ++c) { 5211 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 5212 const PetscInt *cone, *ornt; 5213 PetscInt coneNew[4], orntNew[4]; 5214 PetscInt supportNew[2]; 5215 5216 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5217 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5218 /* Face {a, g, m, h} */ 5219 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5220 orntNew[0] = 0; 5221 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5222 orntNew[1] = 0; 5223 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5224 orntNew[2] = -2; 5225 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5226 orntNew[3] = -2; 5227 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5228 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5229 #if defined(PETSC_USE_DEBUG) 5230 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5231 for (p = 0; p < 4; ++p) { 5232 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); 5233 } 5234 #endif 5235 supportNew[0] = (c - cStart)*4 + 0; 5236 supportNew[1] = (c - cStart)*4 + 1; 5237 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5238 #if defined(PETSC_USE_DEBUG) 5239 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5240 for (p = 0; p < 2; ++p) { 5241 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); 5242 } 5243 #endif 5244 ++newp; 5245 /* Face {g, b, l , m} */ 5246 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5247 orntNew[0] = -2; 5248 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5249 orntNew[1] = 0; 5250 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5251 orntNew[2] = 0; 5252 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5253 orntNew[3] = -2; 5254 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5255 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5256 #if defined(PETSC_USE_DEBUG) 5257 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5258 for (p = 0; p < 4; ++p) { 5259 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); 5260 } 5261 #endif 5262 supportNew[0] = (c - cStart)*4 + 1; 5263 supportNew[1] = (c - cStart)*4 + 2; 5264 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5265 #if defined(PETSC_USE_DEBUG) 5266 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5267 for (p = 0; p < 2; ++p) { 5268 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); 5269 } 5270 #endif 5271 ++newp; 5272 /* Face {c, g, m, i} */ 5273 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5274 orntNew[0] = 0; 5275 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5276 orntNew[1] = 0; 5277 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5278 orntNew[2] = -2; 5279 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5280 orntNew[3] = -2; 5281 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5282 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5283 #if defined(PETSC_USE_DEBUG) 5284 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5285 for (p = 0; p < 4; ++p) { 5286 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); 5287 } 5288 #endif 5289 supportNew[0] = (c - cStart)*4 + 0; 5290 supportNew[1] = (c - cStart)*4 + 2; 5291 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5292 #if defined(PETSC_USE_DEBUG) 5293 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5294 for (p = 0; p < 2; ++p) { 5295 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); 5296 } 5297 #endif 5298 ++newp; 5299 /* Face {d, h, m, i} */ 5300 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5301 orntNew[0] = 0; 5302 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5303 orntNew[1] = 0; 5304 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5305 orntNew[2] = -2; 5306 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5307 orntNew[3] = -2; 5308 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5309 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5310 #if defined(PETSC_USE_DEBUG) 5311 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5312 for (p = 0; p < 4; ++p) { 5313 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); 5314 } 5315 #endif 5316 supportNew[0] = (c - cStart)*4 + 0; 5317 supportNew[1] = (c - cStart)*4 + 3; 5318 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5319 #if defined(PETSC_USE_DEBUG) 5320 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5321 for (p = 0; p < 2; ++p) { 5322 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); 5323 } 5324 #endif 5325 ++newp; 5326 /* Face {h, m, l, e} */ 5327 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5328 orntNew[0] = 0; 5329 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5330 orntNew[1] = -2; 5331 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5332 orntNew[2] = -2; 5333 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5334 orntNew[3] = 0; 5335 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5336 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5337 #if defined(PETSC_USE_DEBUG) 5338 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5339 for (p = 0; p < 4; ++p) { 5340 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); 5341 } 5342 #endif 5343 supportNew[0] = (c - cStart)*4 + 1; 5344 supportNew[1] = (c - cStart)*4 + 3; 5345 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5346 #if defined(PETSC_USE_DEBUG) 5347 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5348 for (p = 0; p < 2; ++p) { 5349 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); 5350 } 5351 #endif 5352 ++newp; 5353 /* Face {i, m, l, f} */ 5354 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5355 orntNew[0] = 0; 5356 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5357 orntNew[1] = -2; 5358 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5359 orntNew[2] = -2; 5360 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5361 orntNew[3] = 0; 5362 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5363 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5364 #if defined(PETSC_USE_DEBUG) 5365 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5366 for (p = 0; p < 4; ++p) { 5367 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); 5368 } 5369 #endif 5370 supportNew[0] = (c - cStart)*4 + 2; 5371 supportNew[1] = (c - cStart)*4 + 3; 5372 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5373 #if defined(PETSC_USE_DEBUG) 5374 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5375 for (p = 0; p < 2; ++p) { 5376 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); 5377 } 5378 #endif 5379 ++newp; 5380 } 5381 /* Split Edges have 2 vertices and the same faces as the parent */ 5382 for (e = eStart; e < eEnd; ++e) { 5383 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5384 5385 for (r = 0; r < 2; ++r) { 5386 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5387 const PetscInt *cone, *ornt, *support; 5388 PetscInt coneNew[2], coneSize, c, supportSize, s; 5389 5390 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5391 coneNew[0] = vStartNew + (cone[0] - vStart); 5392 coneNew[1] = vStartNew + (cone[1] - vStart); 5393 coneNew[(r+1)%2] = newv; 5394 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5395 #if defined(PETSC_USE_DEBUG) 5396 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5397 for (p = 0; p < 2; ++p) { 5398 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); 5399 } 5400 #endif 5401 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5402 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5403 for (s = 0; s < supportSize; ++s) { 5404 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5405 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5406 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5407 for (c = 0; c < coneSize; ++c) { 5408 if (cone[c] == e) break; 5409 } 5410 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 5411 } 5412 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5413 #if defined(PETSC_USE_DEBUG) 5414 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5415 for (p = 0; p < supportSize; ++p) { 5416 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); 5417 } 5418 #endif 5419 } 5420 } 5421 /* Face edges have 2 vertices and 2 + cell faces supports */ 5422 for (f = fStart; f < fEnd; ++f) { 5423 const PetscInt *cone, *ornt, *support; 5424 PetscInt coneSize, supportSize, s; 5425 5426 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5427 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5428 for (r = 0; r < 3; ++r) { 5429 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 5430 PetscInt coneNew[2]; 5431 PetscInt fint[4][3] = { {0, 1, 2}, 5432 {3, 4, 0}, 5433 {2, 5, 3}, 5434 {1, 4, 5} }; 5435 5436 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5437 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5438 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 5439 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5440 #if defined(PETSC_USE_DEBUG) 5441 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5442 for (p = 0; p < 2; ++p) { 5443 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); 5444 } 5445 #endif 5446 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 5447 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 5448 for (s = 0; s < supportSize; ++s) { 5449 PetscInt er; 5450 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5451 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5452 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5453 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 5454 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 5455 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 5456 } 5457 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5458 #if defined(PETSC_USE_DEBUG) 5459 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5460 for (p = 0; p < supportSize + 2; ++p) { 5461 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); 5462 } 5463 #endif 5464 } 5465 } 5466 /* Interior cell edges have 2 vertices and 3 faces */ 5467 for (c = cStart; c < cEnd; ++c) { 5468 const PetscInt *cone; 5469 PetscInt fint[4][3] = { {0,1,2}, 5470 {0,3,4}, 5471 {2,3,5}, 5472 {1,4,5} } ; 5473 5474 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5475 for (r = 0; r < 4; r++) { 5476 PetscInt coneNew[2], supportNew[3]; 5477 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 5478 5479 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5480 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 5481 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5482 #if defined(PETSC_USE_DEBUG) 5483 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5484 for (p = 0; p < 2; ++p) { 5485 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); 5486 } 5487 #endif 5488 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 5489 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 5490 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 5491 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5492 #if defined(PETSC_USE_DEBUG) 5493 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5494 for (p = 0; p < 3; ++p) { 5495 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); 5496 } 5497 #endif 5498 } 5499 } 5500 /* Old vertices have identical supports */ 5501 for (v = vStart; v < vEnd; ++v) { 5502 const PetscInt newp = vStartNew + (v - vStart); 5503 const PetscInt *support, *cone; 5504 PetscInt size, s; 5505 5506 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5507 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5508 for (s = 0; s < size; ++s) { 5509 PetscInt r = 0; 5510 5511 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5512 if (cone[1] == v) r = 1; 5513 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5514 } 5515 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5516 #if defined(PETSC_USE_DEBUG) 5517 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5518 for (p = 0; p < size; ++p) { 5519 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); 5520 } 5521 #endif 5522 } 5523 /* Edge vertices have 2 + faces supports */ 5524 for (e = eStart; e < eEnd; ++e) { 5525 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5526 const PetscInt *cone, *support; 5527 PetscInt size, s; 5528 5529 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5530 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5531 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5532 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5533 for (s = 0; s < size; ++s) { 5534 PetscInt r = 0, coneSize; 5535 5536 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5537 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5538 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 5539 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 5540 } 5541 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5542 #if defined(PETSC_USE_DEBUG) 5543 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5544 for (p = 0; p < 2+size; ++p) { 5545 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); 5546 } 5547 #endif 5548 } 5549 /* Face vertices have 3 + cells supports */ 5550 for (f = fStart; f < fEnd; ++f) { 5551 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5552 const PetscInt *cone, *support; 5553 PetscInt size, s; 5554 5555 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5556 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5557 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5558 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5559 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5560 for (s = 0; s < size; ++s) { 5561 PetscInt r = 0, coneSize; 5562 5563 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5564 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5565 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 5566 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 5567 } 5568 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5569 #if defined(PETSC_USE_DEBUG) 5570 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5571 for (p = 0; p < 3+size; ++p) { 5572 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); 5573 } 5574 #endif 5575 } 5576 /* Interior cell vertices have 4 supports */ 5577 for (c = cStart; c < cEnd; ++c) { 5578 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 5579 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5580 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5581 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5582 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5583 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5584 #if defined(PETSC_USE_DEBUG) 5585 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5586 for (p = 0; p < 4; ++p) { 5587 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); 5588 } 5589 #endif 5590 } 5591 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5592 ierr = DMPlexRestoreFaces_Internal(dm, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5593 break; 5594 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 5595 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 5596 cMax = PetscMin(cEnd, cMax); 5597 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5598 fMax = PetscMin(fEnd, fMax); 5599 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5600 eMax = PetscMin(eEnd, eMax); 5601 ierr = DMPlexGetRawFaces_Internal(dm, DM_POLYTOPE_TETRAHEDRON, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5602 /* All cells have 6 faces */ 5603 for (c = cStart; c < cMax; ++c) { 5604 const PetscInt newp = cStartNew + (c - cStart)*4; 5605 const PetscInt *cone, *ornt; 5606 PetscInt coneNew[6]; 5607 PetscInt orntNew[6]; 5608 5609 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5610 #if defined(PETSC_USE_DEBUG) 5611 for (p = 0; p < 4; ++p) { 5612 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); 5613 } 5614 #endif 5615 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5616 /* A hex */ 5617 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5618 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5619 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5620 orntNew[1] = -4; 5621 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5622 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5623 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5624 orntNew[3] = -1; 5625 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5626 orntNew[4] = 0; 5627 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5628 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5629 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5630 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5631 #if defined(PETSC_USE_DEBUG) 5632 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); 5633 for (p = 0; p < 6; ++p) { 5634 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); 5635 } 5636 #endif 5637 /* B hex */ 5638 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5639 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5640 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5641 orntNew[1] = 0; 5642 coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5643 orntNew[2] = 0; 5644 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5645 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5646 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5647 orntNew[4] = 0; 5648 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5649 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5650 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5651 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5652 #if defined(PETSC_USE_DEBUG) 5653 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); 5654 for (p = 0; p < 6; ++p) { 5655 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); 5656 } 5657 #endif 5658 /* C hex */ 5659 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5660 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5661 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5662 orntNew[1] = -4; 5663 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5664 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5665 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5666 orntNew[3] = -1; 5667 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5668 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5669 coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5670 orntNew[5] = -4; 5671 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5672 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5673 #if defined(PETSC_USE_DEBUG) 5674 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); 5675 for (p = 0; p < 6; ++p) { 5676 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); 5677 } 5678 #endif 5679 /* D hex */ 5680 coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5681 orntNew[0] = 0; 5682 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5683 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5684 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5685 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5686 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5687 orntNew[3] = -1; 5688 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5689 orntNew[4] = 0; 5690 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5691 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5692 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5693 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5694 #if defined(PETSC_USE_DEBUG) 5695 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); 5696 for (p = 0; p < 6; ++p) { 5697 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); 5698 } 5699 #endif 5700 } 5701 for (c = cMax; c < cEnd; ++c) { 5702 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3; 5703 const PetscInt *cone, *ornt; 5704 PetscInt coneNew[6], orntNew[6]; 5705 PetscInt o, of, cf; 5706 5707 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5708 #if defined(PETSC_USE_DEBUG) 5709 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); 5710 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); 5711 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); 5712 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); 5713 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); 5714 #endif 5715 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5716 o = ornt[0] < 0 ? -1 : 1; 5717 o = 1; 5718 /* A hex */ 5719 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5720 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5721 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */ 5722 orntNew[1] = ornt[1] < 0 ? 1 : -1; 5723 cf = 2; 5724 of = ornt[2+cf] < 0 ? -1 : 1; 5725 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */ 5726 orntNew[2] = o*of < 0 ? 0 : -1; 5727 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */ 5728 orntNew[3] = -1; 5729 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */ 5730 orntNew[4] = 0; 5731 cf = 0; 5732 of = ornt[2+cf] < 0 ? -1 : 1; 5733 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */ 5734 orntNew[5] = o*of < 0 ? 1 : -4; 5735 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5736 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5737 #if defined(PETSC_USE_DEBUG) 5738 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); 5739 for (p = 0; p < 6; ++p) { 5740 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); 5741 } 5742 #endif 5743 /* B hex */ 5744 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5745 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5746 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */ 5747 orntNew[1] = ornt[1] < 0 ? 2 : -4; 5748 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */ 5749 orntNew[2] = 0; 5750 cf = 1; 5751 of = ornt[2+cf] < 0 ? -1 : 1; 5752 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */ 5753 orntNew[3] = o*of < 0 ? 0 : -1; 5754 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */ 5755 orntNew[4] = -1; 5756 cf = 0; 5757 of = ornt[2+cf] < 0 ? -1 : 1; 5758 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */ 5759 orntNew[5] = o*of < 0 ? 1 : -4; 5760 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5761 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5762 #if defined(PETSC_USE_DEBUG) 5763 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); 5764 for (p = 0; p < 6; ++p) { 5765 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); 5766 } 5767 #endif 5768 /* C hex */ 5769 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5770 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5771 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */ 5772 orntNew[1] = ornt[1] < 0 ? 0 : -2; 5773 cf = 2; 5774 of = ornt[2+cf] < 0 ? -1 : 1; 5775 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */ 5776 orntNew[2] = o*of < 0 ? 0 : -1; 5777 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */ 5778 orntNew[3] = 0; 5779 cf = 1; 5780 of = ornt[2+cf] < 0 ? -1 : 1; 5781 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */ 5782 orntNew[4] = o*of < 0 ? 0 : -1; 5783 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */ 5784 orntNew[5] = -4; 5785 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5786 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5787 #if defined(PETSC_USE_DEBUG) 5788 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); 5789 for (p = 0; p < 6; ++p) { 5790 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); 5791 } 5792 #endif 5793 } 5794 5795 /* Split faces have 4 edges and the same cells as the parent */ 5796 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5797 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5798 for (f = fStart; f < fMax; ++f) { 5799 const PetscInt newp = fStartNew + (f - fStart)*3; 5800 const PetscInt *cone, *ornt, *support; 5801 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5802 5803 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5804 #if defined(PETSC_USE_DEBUG) 5805 for (p = 0; p < 3; ++p) { 5806 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); 5807 } 5808 #endif 5809 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5810 /* A quad */ 5811 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5812 orntNew[0] = ornt[2]; 5813 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5814 orntNew[1] = ornt[0]; 5815 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5816 orntNew[2] = 0; 5817 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5818 orntNew[3] = -2; 5819 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5820 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5821 #if defined(PETSC_USE_DEBUG) 5822 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); 5823 for (p = 0; p < 4; ++p) { 5824 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); 5825 } 5826 #endif 5827 /* B quad */ 5828 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5829 orntNew[0] = ornt[0]; 5830 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5831 orntNew[1] = ornt[1]; 5832 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5833 orntNew[2] = 0; 5834 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5835 orntNew[3] = -2; 5836 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5837 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5838 #if defined(PETSC_USE_DEBUG) 5839 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); 5840 for (p = 0; p < 4; ++p) { 5841 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); 5842 } 5843 #endif 5844 /* C quad */ 5845 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5846 orntNew[0] = ornt[1]; 5847 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5848 orntNew[1] = ornt[2]; 5849 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5850 orntNew[2] = 0; 5851 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5852 orntNew[3] = -2; 5853 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5854 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5855 #if defined(PETSC_USE_DEBUG) 5856 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); 5857 for (p = 0; p < 4; ++p) { 5858 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); 5859 } 5860 #endif 5861 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5862 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5863 for (r = 0; r < 3; ++r) { 5864 for (s = 0; s < supportSize; ++s) { 5865 PetscInt subf; 5866 5867 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5868 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); 5869 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); 5870 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5871 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5872 for (c = 0; c < coneSize; ++c) { 5873 if (cone[c] == f) break; 5874 } 5875 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5876 if (coneSize == 4) { 5877 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5878 } else if (coneSize == 5) { 5879 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); 5880 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf; 5881 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5882 } 5883 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5884 #if defined(PETSC_USE_DEBUG) 5885 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); 5886 for (p = 0; p < supportSize; ++p) { 5887 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); 5888 } 5889 #endif 5890 } 5891 } 5892 /* Interior faces have 4 edges and 2 cells */ 5893 for (c = cStart; c < cMax; ++c) { 5894 PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6; 5895 const PetscInt *cone, *ornt; 5896 PetscInt coneNew[4], orntNew[4]; 5897 PetscInt supportNew[2]; 5898 5899 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5900 #if defined(PETSC_USE_DEBUG) 5901 for (p = 0; p < 4; ++p) { 5902 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); 5903 } 5904 #endif 5905 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5906 /* Face {a, g, m, h} */ 5907 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5908 orntNew[0] = 0; 5909 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5910 orntNew[1] = 0; 5911 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5912 orntNew[2] = -2; 5913 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5914 orntNew[3] = -2; 5915 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5916 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5917 #if defined(PETSC_USE_DEBUG) 5918 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5919 for (p = 0; p < 4; ++p) { 5920 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); 5921 } 5922 #endif 5923 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5924 supportNew[1] = cStartNew + (c - cStart)*4 + 1; 5925 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5926 #if defined(PETSC_USE_DEBUG) 5927 for (p = 0; p < 2; ++p) { 5928 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); 5929 } 5930 #endif 5931 ++newp; 5932 /* Face {g, b, l , m} */ 5933 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5934 orntNew[0] = -2; 5935 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5936 orntNew[1] = 0; 5937 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5938 orntNew[2] = 0; 5939 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5940 orntNew[3] = -2; 5941 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5942 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5943 #if defined(PETSC_USE_DEBUG) 5944 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5945 for (p = 0; p < 4; ++p) { 5946 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); 5947 } 5948 #endif 5949 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5950 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5951 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5952 #if defined(PETSC_USE_DEBUG) 5953 for (p = 0; p < 2; ++p) { 5954 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); 5955 } 5956 #endif 5957 ++newp; 5958 /* Face {c, g, m, i} */ 5959 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5960 orntNew[0] = 0; 5961 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5962 orntNew[1] = 0; 5963 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5964 orntNew[2] = -2; 5965 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5966 orntNew[3] = -2; 5967 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5968 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5969 #if defined(PETSC_USE_DEBUG) 5970 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5971 for (p = 0; p < 4; ++p) { 5972 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); 5973 } 5974 #endif 5975 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5976 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5977 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5978 #if defined(PETSC_USE_DEBUG) 5979 for (p = 0; p < 2; ++p) { 5980 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); 5981 } 5982 #endif 5983 ++newp; 5984 /* Face {d, h, m, i} */ 5985 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5986 orntNew[0] = 0; 5987 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5988 orntNew[1] = 0; 5989 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5990 orntNew[2] = -2; 5991 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5992 orntNew[3] = -2; 5993 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5994 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5995 #if defined(PETSC_USE_DEBUG) 5996 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5997 for (p = 0; p < 4; ++p) { 5998 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); 5999 } 6000 #endif 6001 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 6002 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6003 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6004 #if defined(PETSC_USE_DEBUG) 6005 for (p = 0; p < 2; ++p) { 6006 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); 6007 } 6008 #endif 6009 ++newp; 6010 /* Face {h, m, l, e} */ 6011 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6012 orntNew[0] = 0; 6013 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6014 orntNew[1] = -2; 6015 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 6016 orntNew[2] = -2; 6017 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6018 orntNew[3] = 0; 6019 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6020 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6021 #if defined(PETSC_USE_DEBUG) 6022 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6023 for (p = 0; p < 4; ++p) { 6024 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); 6025 } 6026 #endif 6027 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 6028 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6029 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6030 #if defined(PETSC_USE_DEBUG) 6031 for (p = 0; p < 2; ++p) { 6032 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); 6033 } 6034 #endif 6035 ++newp; 6036 /* Face {i, m, l, f} */ 6037 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6038 orntNew[0] = 0; 6039 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6040 orntNew[1] = -2; 6041 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 6042 orntNew[2] = -2; 6043 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 6044 orntNew[3] = 0; 6045 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6046 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6047 #if defined(PETSC_USE_DEBUG) 6048 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6049 for (p = 0; p < 4; ++p) { 6050 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); 6051 } 6052 #endif 6053 supportNew[0] = cStartNew + (c - cStart)*4 + 2; 6054 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6055 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6056 #if defined(PETSC_USE_DEBUG) 6057 for (p = 0; p < 2; ++p) { 6058 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); 6059 } 6060 #endif 6061 ++newp; 6062 } 6063 /* Hybrid split faces have 4 edges and same cells */ 6064 for (f = fMax; f < fEnd; ++f) { 6065 const PetscInt *cone, *ornt, *support; 6066 PetscInt coneNew[4], orntNew[4]; 6067 PetscInt size, s; 6068 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2; 6069 6070 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6071 #if defined(PETSC_USE_DEBUG) 6072 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); 6073 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); 6074 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); 6075 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); 6076 #endif 6077 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6078 /* A face */ 6079 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 6080 orntNew[0] = ornt[0]; 6081 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 6082 orntNew[1] = 0; 6083 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 6084 orntNew[2] = ornt[1] < 0 ? 0 : -2; 6085 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax); 6086 orntNew[3] = ornt[2] < 0 ? 0 : -2; 6087 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6088 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6089 #if defined(PETSC_USE_DEBUG) 6090 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6091 for (p = 0; p < 4; ++p) { 6092 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); 6093 } 6094 #endif 6095 6096 /* B face */ 6097 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 6098 orntNew[0] = ornt[0]; 6099 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax); 6100 orntNew[1] = ornt[3]; 6101 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 6102 orntNew[2] = ornt[1] < 0 ? 0 : -2; 6103 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 6104 orntNew[3] = -2; 6105 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6106 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6107 #if defined(PETSC_USE_DEBUG) 6108 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); 6109 for (p = 0; p < 4; ++p) { 6110 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); 6111 } 6112 #endif 6113 6114 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6115 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6116 for (r = 0; r < 2; ++r) { 6117 for (s = 0; s < size; ++s) { 6118 const PetscInt *coneCell, *orntCell; 6119 PetscInt coneSize, o, of, c; 6120 6121 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6122 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); 6123 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6124 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6125 o = orntCell[0] < 0 ? -1 : 1; 6126 o = 1; 6127 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 6128 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); 6129 if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 6130 of = orntCell[c] < 0 ? -1 : 1; 6131 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (c-2 + (o*of < 0 ? 1-r : r))%3; 6132 } 6133 ierr = DMPlexSetSupport(rdm, newp + r, supportRef);CHKERRQ(ierr); 6134 #if defined(PETSC_USE_DEBUG) 6135 for (p = 0; p < size; ++p) { 6136 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); 6137 } 6138 #endif 6139 } 6140 } 6141 /* Interior hybrid faces have 4 edges and 2 cells */ 6142 for (c = cMax; c < cEnd; ++c) { 6143 PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3; 6144 const PetscInt *cone, *ornt; 6145 PetscInt coneNew[4], orntNew[4]; 6146 PetscInt supportNew[2]; 6147 6148 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6149 #if defined(PETSC_USE_DEBUG) 6150 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); 6151 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); 6152 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); 6153 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); 6154 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); 6155 #endif 6156 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6157 /* Face {a, g, h, d} */ 6158 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 6159 orntNew[0] = 0; 6160 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6161 orntNew[1] = 0; 6162 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 6163 orntNew[2] = -2; 6164 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax); 6165 orntNew[3] = -2; 6166 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6167 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6168 #if defined(PETSC_USE_DEBUG) 6169 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6170 for (p = 0; p < 4; ++p) { 6171 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); 6172 } 6173 #endif 6174 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6175 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6176 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6177 #if defined(PETSC_USE_DEBUG) 6178 for (p = 0; p < 2; ++p) { 6179 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); 6180 } 6181 #endif 6182 ++newp; 6183 /* Face {b, g, h, l} */ 6184 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 6185 orntNew[0] = 0; 6186 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6187 orntNew[1] = 0; 6188 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6189 orntNew[2] = -2; 6190 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax); 6191 orntNew[3] = -2; 6192 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6193 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6194 #if defined(PETSC_USE_DEBUG) 6195 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6196 for (p = 0; p < 4; ++p) { 6197 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); 6198 } 6199 #endif 6200 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6201 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6202 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6203 #if defined(PETSC_USE_DEBUG) 6204 for (p = 0; p < 2; ++p) { 6205 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); 6206 } 6207 #endif 6208 ++newp; 6209 /* Face {c, g, h, f} */ 6210 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 6211 orntNew[0] = 0; 6212 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6213 orntNew[1] = 0; 6214 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 6215 orntNew[2] = -2; 6216 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax); 6217 orntNew[3] = -2; 6218 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6219 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6220 #if defined(PETSC_USE_DEBUG) 6221 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6222 for (p = 0; p < 4; ++p) { 6223 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); 6224 } 6225 #endif 6226 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6227 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6228 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6229 #if defined(PETSC_USE_DEBUG) 6230 for (p = 0; p < 2; ++p) { 6231 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); 6232 } 6233 #endif 6234 } 6235 /* Face edges have 2 vertices and 2 + cell faces supports */ 6236 for (f = fStart; f < fMax; ++f) { 6237 const PetscInt *cone, *ornt, *support; 6238 PetscInt coneSize, supportSize, s; 6239 6240 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6241 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6242 for (r = 0; r < 3; ++r) { 6243 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 6244 PetscInt coneNew[2]; 6245 PetscInt fint[4][3] = { {0, 1, 2}, 6246 {3, 4, 0}, 6247 {2, 5, 3}, 6248 {1, 4, 5} }; 6249 6250 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6251 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); 6252 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6253 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 6254 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6255 #if defined(PETSC_USE_DEBUG) 6256 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6257 for (p = 0; p < 2; ++p) { 6258 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); 6259 } 6260 #endif 6261 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 6262 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 6263 for (s = 0; s < supportSize; ++s) { 6264 PetscInt er; 6265 6266 supportRef[2+s] = -1; 6267 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6268 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); 6269 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); 6270 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6271 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6272 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6273 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 6274 if (coneSize == 4) { 6275 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 6276 } else if (coneSize == 5) { 6277 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); 6278 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er; 6279 } 6280 } 6281 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6282 #if defined(PETSC_USE_DEBUG) 6283 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6284 for (p = 0; p < supportSize + 2; ++p) { 6285 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); 6286 } 6287 #endif 6288 } 6289 } 6290 /* Interior cell edges have 2 vertices and 3 faces */ 6291 for (c = cStart; c < cMax; ++c) { 6292 const PetscInt *cone; 6293 PetscInt fint[4][3] = { {0,1,2}, 6294 {0,3,4}, 6295 {2,3,5}, 6296 {1,4,5} } ; 6297 6298 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6299 for (r = 0; r < 4; r++) { 6300 PetscInt coneNew[2], supportNew[3]; 6301 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 6302 6303 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); 6304 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6305 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart; 6306 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6307 #if defined(PETSC_USE_DEBUG) 6308 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6309 for (p = 0; p < 2; ++p) { 6310 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); 6311 } 6312 #endif 6313 supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0]; 6314 supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1]; 6315 supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2]; 6316 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6317 #if defined(PETSC_USE_DEBUG) 6318 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6319 for (p = 0; p < 3; ++p) { 6320 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); 6321 } 6322 #endif 6323 } 6324 } 6325 /* Hybrid edges have two vertices and the same faces */ 6326 for (e = eMax; e < eEnd; ++e) { 6327 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 6328 const PetscInt *cone, *support, *fcone; 6329 PetscInt coneNew[2], size, fsize, s; 6330 6331 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6332 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6333 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6334 coneNew[0] = vStartNew + (cone[0] - vStart); 6335 coneNew[1] = vStartNew + (cone[1] - vStart); 6336 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6337 #if defined(PETSC_USE_DEBUG) 6338 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is a edge [%D, %D)", newp, eStartNew, eEndNew); 6339 for (p = 0; p < 2; ++p) { 6340 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); 6341 } 6342 #endif 6343 for (s = 0; s < size; ++s) { 6344 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6345 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6346 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6347 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 6348 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2; 6349 } 6350 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6351 #if defined(PETSC_USE_DEBUG) 6352 for (p = 0; p < size; ++p) { 6353 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); 6354 } 6355 #endif 6356 } 6357 /* Hybrid face edges have 2 vertices and 2 + cell faces supports */ 6358 for (f = fMax; f < fEnd; ++f) { 6359 const PetscInt *cone, *ornt, *support; 6360 PetscInt coneSize, supportSize; 6361 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax; 6362 PetscInt coneNew[2], s; 6363 6364 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6365 #if defined(PETSC_USE_DEBUG) 6366 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); 6367 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); 6368 #endif 6369 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6370 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6371 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6372 #if defined(PETSC_USE_DEBUG) 6373 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6374 for (p = 0; p < 2; ++p) { 6375 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); 6376 } 6377 #endif 6378 supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0; 6379 supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1; 6380 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6381 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6382 for (s = 0; s < supportSize; ++s) { 6383 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6384 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); 6385 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6386 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6387 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6388 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); 6389 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2; 6390 } 6391 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6392 #if defined(PETSC_USE_DEBUG) 6393 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6394 for (p = 0; p < supportSize + 2; ++p) { 6395 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); 6396 } 6397 #endif 6398 } 6399 /* Hybrid cell edges have 2 vertices and 3 faces */ 6400 for (c = cMax; c < cEnd; ++c) { 6401 PetscInt coneNew[2], supportNew[3]; 6402 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6403 const PetscInt *cone; 6404 6405 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6406 #if defined(PETSC_USE_DEBUG) 6407 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); 6408 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); 6409 #endif 6410 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6411 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6412 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6413 #if defined(PETSC_USE_DEBUG) 6414 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6415 for (p = 0; p < 2; ++p) { 6416 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); 6417 } 6418 #endif 6419 supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 6420 supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 6421 supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 6422 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6423 #if defined(PETSC_USE_DEBUG) 6424 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6425 for (p = 0; p < 3; ++p) { 6426 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); 6427 } 6428 #endif 6429 } 6430 /* Old vertices have identical supports */ 6431 for (v = vStart; v < vEnd; ++v) { 6432 const PetscInt newp = vStartNew + (v - vStart); 6433 const PetscInt *support, *cone; 6434 PetscInt size, s; 6435 6436 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6437 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6438 for (s = 0; s < size; ++s) { 6439 const PetscInt e = support[s]; 6440 6441 supportRef[s] = -1; 6442 if (eStart <= e) { 6443 if (e < eMax) { 6444 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6445 supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0); 6446 } else if (e < eEnd) { 6447 supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax; 6448 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6449 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6450 } 6451 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6452 #if defined(PETSC_USE_DEBUG) 6453 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6454 for (p = 0; p < size; ++p) { 6455 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); 6456 } 6457 #endif 6458 } 6459 /* Interior edge vertices have 2 + faces supports */ 6460 for (e = eStart; e < eMax; ++e) { 6461 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6462 const PetscInt *cone, *support; 6463 PetscInt size, s; 6464 6465 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6466 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6467 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6468 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6469 for (s = 0; s < size; ++s) { 6470 PetscInt r, coneSize; 6471 6472 supportRef[2+s] = -1; 6473 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6474 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); 6475 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); 6476 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6477 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 6478 if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r; 6479 else if (coneSize == 4) { 6480 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); 6481 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax; 6482 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6483 } 6484 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6485 #if defined(PETSC_USE_DEBUG) 6486 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6487 for (p = 0; p < 2+size; ++p) { 6488 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); 6489 } 6490 #endif 6491 } 6492 /* Split Edges have 2 vertices and the same faces as the parent */ 6493 for (e = eStart; e < eMax; ++e) { 6494 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6495 6496 for (r = 0; r < 2; ++r) { 6497 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6498 const PetscInt *cone, *ornt, *support; 6499 PetscInt coneNew[2], coneSize, c, supportSize, s; 6500 6501 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6502 coneNew[0] = vStartNew + (cone[0] - vStart); 6503 coneNew[1] = vStartNew + (cone[1] - vStart); 6504 coneNew[(r+1)%2] = newv; 6505 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6506 #if defined(PETSC_USE_DEBUG) 6507 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6508 for (p = 0; p < 2; ++p) { 6509 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); 6510 } 6511 #endif 6512 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6513 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6514 for (s = 0; s < supportSize; ++s) { 6515 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6516 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); 6517 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); 6518 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6519 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6520 for (c = 0; c < coneSize; ++c) { 6521 if (cone[c] == e) break; 6522 } 6523 if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 6524 else if (coneSize == 4) { 6525 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); 6526 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6527 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6528 } 6529 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6530 #if defined(PETSC_USE_DEBUG) 6531 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6532 for (p = 0; p < supportSize; ++p) { 6533 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); 6534 } 6535 #endif 6536 } 6537 } 6538 /* Face vertices have 3 + cells supports */ 6539 for (f = fStart; f < fMax; ++f) { 6540 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6541 const PetscInt *cone, *support; 6542 PetscInt size, s; 6543 6544 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6545 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6546 supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 6547 supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 6548 supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 6549 for (s = 0; s < size; ++s) { 6550 PetscInt r, coneSize; 6551 6552 supportRef[3+s] = -1; 6553 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6554 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); 6555 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); 6556 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6557 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 6558 if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r; 6559 else if (coneSize == 5) { 6560 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); 6561 supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax; 6562 } 6563 } 6564 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6565 #if defined(PETSC_USE_DEBUG) 6566 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6567 for (p = 0; p < 3+size; ++p) { 6568 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); 6569 } 6570 #endif 6571 } 6572 /* Interior cell vertices have 4 supports */ 6573 for (c = cStart; c < cMax; ++c) { 6574 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 6575 6576 supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 6577 supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6578 supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6579 supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6580 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6581 #if defined(PETSC_USE_DEBUG) 6582 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6583 for (p = 0; p < 4; ++p) { 6584 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); 6585 } 6586 #endif 6587 } 6588 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6589 ierr = DMPlexRestoreFaces_Internal(dm, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 6590 break; 6591 case REFINER_HEX_3D: 6592 /* 6593 Bottom (viewed from top) Top 6594 1---------2---------2 7---------2---------6 6595 | | | | | | 6596 | B 2 C | | H 2 G | 6597 | | | | | | 6598 3----3----0----1----1 3----3----0----1----1 6599 | | | | | | 6600 | A 0 D | | E 0 F | 6601 | | | | | | 6602 0---------0---------3 4---------0---------5 6603 */ 6604 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 6605 for (c = cStart; c < cEnd; ++c) { 6606 const PetscInt newp = (c - cStart)*8; 6607 const PetscInt *cone, *ornt; 6608 PetscInt coneNew[6], orntNew[6]; 6609 6610 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6611 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6612 /* A hex */ 6613 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 6614 orntNew[0] = ornt[0]; 6615 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6616 orntNew[1] = 0; 6617 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 6618 orntNew[2] = ornt[2]; 6619 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6620 orntNew[3] = 0; 6621 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6622 orntNew[4] = 0; 6623 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 6624 orntNew[5] = ornt[5]; 6625 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 6626 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 6627 #if defined(PETSC_USE_DEBUG) 6628 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); 6629 for (p = 0; p < 6; ++p) { 6630 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); 6631 } 6632 #endif 6633 /* B hex */ 6634 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 6635 orntNew[0] = ornt[0]; 6636 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6637 orntNew[1] = 0; 6638 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6639 orntNew[2] = -1; 6640 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 6641 orntNew[3] = ornt[3]; 6642 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6643 orntNew[4] = 0; 6644 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 6645 orntNew[5] = ornt[5]; 6646 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6647 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6648 #if defined(PETSC_USE_DEBUG) 6649 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); 6650 for (p = 0; p < 6; ++p) { 6651 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); 6652 } 6653 #endif 6654 /* C hex */ 6655 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 6656 orntNew[0] = ornt[0]; 6657 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6658 orntNew[1] = 0; 6659 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6660 orntNew[2] = -1; 6661 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 6662 orntNew[3] = ornt[3]; 6663 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 6664 orntNew[4] = ornt[4]; 6665 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6666 orntNew[5] = -4; 6667 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 6668 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 6669 #if defined(PETSC_USE_DEBUG) 6670 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); 6671 for (p = 0; p < 6; ++p) { 6672 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); 6673 } 6674 #endif 6675 /* D hex */ 6676 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 6677 orntNew[0] = ornt[0]; 6678 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6679 orntNew[1] = 0; 6680 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 6681 orntNew[2] = ornt[2]; 6682 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6683 orntNew[3] = 0; 6684 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 6685 orntNew[4] = ornt[4]; 6686 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6687 orntNew[5] = -4; 6688 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 6689 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 6690 #if defined(PETSC_USE_DEBUG) 6691 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); 6692 for (p = 0; p < 6; ++p) { 6693 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); 6694 } 6695 #endif 6696 /* E hex */ 6697 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6698 orntNew[0] = -4; 6699 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 6700 orntNew[1] = ornt[1]; 6701 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 6702 orntNew[2] = ornt[2]; 6703 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6704 orntNew[3] = 0; 6705 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6706 orntNew[4] = -1; 6707 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 6708 orntNew[5] = ornt[5]; 6709 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 6710 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 6711 #if defined(PETSC_USE_DEBUG) 6712 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); 6713 for (p = 0; p < 6; ++p) { 6714 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); 6715 } 6716 #endif 6717 /* F hex */ 6718 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6719 orntNew[0] = -4; 6720 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 6721 orntNew[1] = ornt[1]; 6722 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 6723 orntNew[2] = ornt[2]; 6724 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6725 orntNew[3] = -1; 6726 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 6727 orntNew[4] = ornt[4]; 6728 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6729 orntNew[5] = 1; 6730 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 6731 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 6732 #if defined(PETSC_USE_DEBUG) 6733 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); 6734 for (p = 0; p < 6; ++p) { 6735 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); 6736 } 6737 #endif 6738 /* G hex */ 6739 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6740 orntNew[0] = -4; 6741 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 6742 orntNew[1] = ornt[1]; 6743 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6744 orntNew[2] = 0; 6745 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 6746 orntNew[3] = ornt[3]; 6747 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 6748 orntNew[4] = ornt[4]; 6749 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6750 orntNew[5] = -3; 6751 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 6752 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 6753 #if defined(PETSC_USE_DEBUG) 6754 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); 6755 for (p = 0; p < 6; ++p) { 6756 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); 6757 } 6758 #endif 6759 /* H hex */ 6760 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6761 orntNew[0] = -4; 6762 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 6763 orntNew[1] = ornt[1]; 6764 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6765 orntNew[2] = -1; 6766 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 6767 orntNew[3] = ornt[3]; 6768 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6769 orntNew[4] = 3; 6770 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 6771 orntNew[5] = ornt[5]; 6772 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 6773 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 6774 #if defined(PETSC_USE_DEBUG) 6775 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); 6776 for (p = 0; p < 6; ++p) { 6777 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); 6778 } 6779 #endif 6780 } 6781 /* Split faces have 4 edges and the same cells as the parent */ 6782 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6783 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 6784 for (f = fStart; f < fEnd; ++f) { 6785 for (r = 0; r < 4; ++r) { 6786 /* TODO: This can come from GetFaces_Internal() */ 6787 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}; 6788 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 6789 const PetscInt *cone, *ornt, *support; 6790 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 6791 6792 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6793 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6794 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 6795 orntNew[(r+3)%4] = ornt[(r+3)%4]; 6796 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 6797 orntNew[(r+0)%4] = ornt[r]; 6798 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6799 orntNew[(r+1)%4] = 0; 6800 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 6801 orntNew[(r+2)%4] = -2; 6802 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6803 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6804 #if defined(PETSC_USE_DEBUG) 6805 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6806 for (p = 0; p < 4; ++p) { 6807 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); 6808 } 6809 #endif 6810 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6811 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6812 for (s = 0; s < supportSize; ++s) { 6813 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6814 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6815 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6816 for (c = 0; c < coneSize; ++c) { 6817 if (cone[c] == f) break; 6818 } 6819 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 6820 } 6821 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6822 #if defined(PETSC_USE_DEBUG) 6823 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6824 for (p = 0; p < supportSize; ++p) { 6825 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); 6826 } 6827 #endif 6828 } 6829 } 6830 /* Interior faces have 4 edges and 2 cells */ 6831 for (c = cStart; c < cEnd; ++c) { 6832 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}; 6833 const PetscInt *cone, *ornt; 6834 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 6835 6836 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6837 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6838 /* A-D face */ 6839 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 6840 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 6841 orntNew[0] = 0; 6842 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6843 orntNew[1] = 0; 6844 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6845 orntNew[2] = -2; 6846 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 6847 orntNew[3] = -2; 6848 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6849 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6850 #if defined(PETSC_USE_DEBUG) 6851 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6852 for (p = 0; p < 4; ++p) { 6853 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); 6854 } 6855 #endif 6856 /* C-D face */ 6857 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 6858 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 6859 orntNew[0] = 0; 6860 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6861 orntNew[1] = 0; 6862 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6863 orntNew[2] = -2; 6864 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 6865 orntNew[3] = -2; 6866 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6867 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6868 #if defined(PETSC_USE_DEBUG) 6869 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6870 for (p = 0; p < 4; ++p) { 6871 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); 6872 } 6873 #endif 6874 /* B-C face */ 6875 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 6876 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 6877 orntNew[0] = -2; 6878 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 6879 orntNew[1] = 0; 6880 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6881 orntNew[2] = 0; 6882 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6883 orntNew[3] = -2; 6884 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6885 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6886 #if defined(PETSC_USE_DEBUG) 6887 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6888 for (p = 0; p < 4; ++p) { 6889 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); 6890 } 6891 #endif 6892 /* A-B face */ 6893 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 6894 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 6895 orntNew[0] = -2; 6896 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 6897 orntNew[1] = 0; 6898 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6899 orntNew[2] = 0; 6900 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6901 orntNew[3] = -2; 6902 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6903 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6904 #if defined(PETSC_USE_DEBUG) 6905 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6906 for (p = 0; p < 4; ++p) { 6907 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); 6908 } 6909 #endif 6910 /* E-F face */ 6911 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 6912 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6913 orntNew[0] = -2; 6914 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 6915 orntNew[1] = -2; 6916 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 6917 orntNew[2] = 0; 6918 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6919 orntNew[3] = 0; 6920 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6921 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6922 #if defined(PETSC_USE_DEBUG) 6923 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6924 for (p = 0; p < 4; ++p) { 6925 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); 6926 } 6927 #endif 6928 /* F-G face */ 6929 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 6930 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6931 orntNew[0] = -2; 6932 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 6933 orntNew[1] = -2; 6934 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 6935 orntNew[2] = 0; 6936 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6937 orntNew[3] = 0; 6938 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6939 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6940 #if defined(PETSC_USE_DEBUG) 6941 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6942 for (p = 0; p < 4; ++p) { 6943 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); 6944 } 6945 #endif 6946 /* G-H face */ 6947 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 6948 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 6949 orntNew[0] = -2; 6950 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 6951 orntNew[1] = 0; 6952 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6953 orntNew[2] = 0; 6954 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6955 orntNew[3] = -2; 6956 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6957 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6958 #if defined(PETSC_USE_DEBUG) 6959 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6960 for (p = 0; p < 4; ++p) { 6961 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); 6962 } 6963 #endif 6964 /* E-H face */ 6965 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 6966 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6967 orntNew[0] = -2; 6968 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 6969 orntNew[1] = -2; 6970 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 6971 orntNew[2] = 0; 6972 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6973 orntNew[3] = 0; 6974 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6975 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6976 #if defined(PETSC_USE_DEBUG) 6977 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6978 for (p = 0; p < 4; ++p) { 6979 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); 6980 } 6981 #endif 6982 /* A-E face */ 6983 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 6984 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 6985 orntNew[0] = 0; 6986 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6987 orntNew[1] = 0; 6988 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6989 orntNew[2] = -2; 6990 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 6991 orntNew[3] = -2; 6992 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6993 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6994 #if defined(PETSC_USE_DEBUG) 6995 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6996 for (p = 0; p < 4; ++p) { 6997 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); 6998 } 6999 #endif 7000 /* D-F face */ 7001 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 7002 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7003 orntNew[0] = -2; 7004 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7005 orntNew[1] = 0; 7006 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 7007 orntNew[2] = 0; 7008 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 7009 orntNew[3] = -2; 7010 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7011 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7012 #if defined(PETSC_USE_DEBUG) 7013 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7014 for (p = 0; p < 4; ++p) { 7015 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); 7016 } 7017 #endif 7018 /* C-G face */ 7019 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 7020 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 7021 orntNew[0] = -2; 7022 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7023 orntNew[1] = -2; 7024 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7025 orntNew[2] = 0; 7026 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 7027 orntNew[3] = 0; 7028 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7029 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7030 #if defined(PETSC_USE_DEBUG) 7031 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7032 for (p = 0; p < 4; ++p) { 7033 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); 7034 } 7035 #endif 7036 /* B-H face */ 7037 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 7038 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 7039 orntNew[0] = 0; 7040 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 7041 orntNew[1] = -2; 7042 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7043 orntNew[2] = -2; 7044 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7045 orntNew[3] = 0; 7046 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7047 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7048 #if defined(PETSC_USE_DEBUG) 7049 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7050 for (p = 0; p < 4; ++p) { 7051 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); 7052 } 7053 #endif 7054 for (r = 0; r < 12; ++r) { 7055 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 7056 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7057 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7058 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7059 #if defined(PETSC_USE_DEBUG) 7060 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7061 for (p = 0; p < 2; ++p) { 7062 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); 7063 } 7064 #endif 7065 } 7066 } 7067 /* Split edges have 2 vertices and the same faces as the parent */ 7068 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7069 for (e = eStart; e < eEnd; ++e) { 7070 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7071 7072 for (r = 0; r < 2; ++r) { 7073 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7074 const PetscInt *cone, *ornt, *support; 7075 PetscInt coneNew[2], coneSize, c, supportSize, s; 7076 7077 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7078 coneNew[0] = vStartNew + (cone[0] - vStart); 7079 coneNew[1] = vStartNew + (cone[1] - vStart); 7080 coneNew[(r+1)%2] = newv; 7081 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7082 #if defined(PETSC_USE_DEBUG) 7083 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7084 for (p = 0; p < 2; ++p) { 7085 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); 7086 } 7087 #endif 7088 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7089 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7090 for (s = 0; s < supportSize; ++s) { 7091 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7092 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7093 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7094 for (c = 0; c < coneSize; ++c) { 7095 if (cone[c] == e) break; 7096 } 7097 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 7098 } 7099 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7100 #if defined(PETSC_USE_DEBUG) 7101 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7102 for (p = 0; p < supportSize; ++p) { 7103 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); 7104 } 7105 #endif 7106 } 7107 } 7108 /* Face edges have 2 vertices and 2+cells faces */ 7109 for (f = fStart; f < fEnd; ++f) { 7110 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}; 7111 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7112 const PetscInt *cone, *coneCell, *orntCell, *support; 7113 PetscInt coneNew[2], coneSize, c, supportSize, s; 7114 7115 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7116 for (r = 0; r < 4; ++r) { 7117 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7118 7119 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7120 coneNew[1] = newv; 7121 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7122 #if defined(PETSC_USE_DEBUG) 7123 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7124 for (p = 0; p < 2; ++p) { 7125 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); 7126 } 7127 #endif 7128 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7129 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7130 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7131 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7132 for (s = 0; s < supportSize; ++s) { 7133 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7134 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7135 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7136 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7137 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7138 } 7139 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7140 #if defined(PETSC_USE_DEBUG) 7141 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7142 for (p = 0; p < 2+supportSize; ++p) { 7143 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); 7144 } 7145 #endif 7146 } 7147 } 7148 /* Cell edges have 2 vertices and 4 faces */ 7149 for (c = cStart; c < cEnd; ++c) { 7150 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}; 7151 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7152 const PetscInt *cone; 7153 PetscInt coneNew[2], supportNew[4]; 7154 7155 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7156 for (r = 0; r < 6; ++r) { 7157 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7158 7159 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 7160 coneNew[1] = newv; 7161 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7162 #if defined(PETSC_USE_DEBUG) 7163 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7164 for (p = 0; p < 2; ++p) { 7165 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); 7166 } 7167 #endif 7168 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7169 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7170 #if defined(PETSC_USE_DEBUG) 7171 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7172 for (p = 0; p < 4; ++p) { 7173 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); 7174 } 7175 #endif 7176 } 7177 } 7178 /* Old vertices have identical supports */ 7179 for (v = vStart; v < vEnd; ++v) { 7180 const PetscInt newp = vStartNew + (v - vStart); 7181 const PetscInt *support, *cone; 7182 PetscInt size, s; 7183 7184 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 7185 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 7186 for (s = 0; s < size; ++s) { 7187 PetscInt r = 0; 7188 7189 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7190 if (cone[1] == v) r = 1; 7191 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 7192 } 7193 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7194 #if defined(PETSC_USE_DEBUG) 7195 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7196 for (p = 0; p < size; ++p) { 7197 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); 7198 } 7199 #endif 7200 } 7201 /* Edge vertices have 2 + faces supports */ 7202 for (e = eStart; e < eEnd; ++e) { 7203 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 7204 const PetscInt *cone, *support; 7205 PetscInt size, s; 7206 7207 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7208 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7209 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 7210 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 7211 for (s = 0; s < size; ++s) { 7212 PetscInt r; 7213 7214 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7215 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 7216 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 7217 } 7218 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7219 #if defined(PETSC_USE_DEBUG) 7220 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7221 for (p = 0; p < 2+size; ++p) { 7222 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); 7223 } 7224 #endif 7225 } 7226 /* Face vertices have 4 + cells supports */ 7227 for (f = fStart; f < fEnd; ++f) { 7228 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7229 const PetscInt *cone, *support; 7230 PetscInt size, s; 7231 7232 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7233 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7234 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7235 for (s = 0; s < size; ++s) { 7236 PetscInt r; 7237 7238 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7239 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 7240 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 7241 } 7242 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7243 #if defined(PETSC_USE_DEBUG) 7244 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7245 for (p = 0; p < 4+size; ++p) { 7246 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); 7247 } 7248 #endif 7249 } 7250 /* Cell vertices have 6 supports */ 7251 for (c = cStart; c < cEnd; ++c) { 7252 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7253 PetscInt supportNew[6]; 7254 7255 for (r = 0; r < 6; ++r) { 7256 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7257 } 7258 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7259 } 7260 ierr = PetscFree(supportRef);CHKERRQ(ierr); 7261 break; 7262 case REFINER_HYBRID_HEX_3D: 7263 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 7264 /* 7265 Bottom (viewed from top) Top 7266 1---------2---------2 7---------2---------6 7267 | | | | | | 7268 | B 2 C | | H 2 G | 7269 | | | | | | 7270 3----3----0----1----1 3----3----0----1----1 7271 | | | | | | 7272 | A 0 D | | E 0 F | 7273 | | | | | | 7274 0---------0---------3 4---------0---------5 7275 */ 7276 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 7277 for (c = cStart; c < cMax; ++c) { 7278 const PetscInt newp = (c - cStart)*8; 7279 const PetscInt *cone, *ornt; 7280 PetscInt coneNew[6], orntNew[6]; 7281 7282 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7283 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7284 /* A hex */ 7285 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 7286 orntNew[0] = ornt[0]; 7287 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7288 orntNew[1] = 0; 7289 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 7290 orntNew[2] = ornt[2]; 7291 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7292 orntNew[3] = 0; 7293 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7294 orntNew[4] = 0; 7295 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 7296 orntNew[5] = ornt[5]; 7297 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 7298 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 7299 #if defined(PETSC_USE_DEBUG) 7300 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); 7301 for (p = 0; p < 6; ++p) { 7302 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); 7303 } 7304 #endif 7305 /* B hex */ 7306 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 7307 orntNew[0] = ornt[0]; 7308 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7309 orntNew[1] = 0; 7310 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7311 orntNew[2] = -1; 7312 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 7313 orntNew[3] = ornt[3]; 7314 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7315 orntNew[4] = 0; 7316 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 7317 orntNew[5] = ornt[5]; 7318 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 7319 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 7320 #if defined(PETSC_USE_DEBUG) 7321 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); 7322 for (p = 0; p < 6; ++p) { 7323 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); 7324 } 7325 #endif 7326 /* C hex */ 7327 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 7328 orntNew[0] = ornt[0]; 7329 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7330 orntNew[1] = 0; 7331 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7332 orntNew[2] = -1; 7333 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 7334 orntNew[3] = ornt[3]; 7335 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 7336 orntNew[4] = ornt[4]; 7337 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7338 orntNew[5] = -4; 7339 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 7340 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 7341 #if defined(PETSC_USE_DEBUG) 7342 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); 7343 for (p = 0; p < 6; ++p) { 7344 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); 7345 } 7346 #endif 7347 /* D hex */ 7348 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 7349 orntNew[0] = ornt[0]; 7350 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7351 orntNew[1] = 0; 7352 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 7353 orntNew[2] = ornt[2]; 7354 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7355 orntNew[3] = 0; 7356 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 7357 orntNew[4] = ornt[4]; 7358 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7359 orntNew[5] = -4; 7360 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 7361 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 7362 #if defined(PETSC_USE_DEBUG) 7363 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); 7364 for (p = 0; p < 6; ++p) { 7365 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); 7366 } 7367 #endif 7368 /* E hex */ 7369 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7370 orntNew[0] = -4; 7371 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 7372 orntNew[1] = ornt[1]; 7373 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 7374 orntNew[2] = ornt[2]; 7375 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7376 orntNew[3] = 0; 7377 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7378 orntNew[4] = -1; 7379 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 7380 orntNew[5] = ornt[5]; 7381 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 7382 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 7383 #if defined(PETSC_USE_DEBUG) 7384 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); 7385 for (p = 0; p < 6; ++p) { 7386 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); 7387 } 7388 #endif 7389 /* F hex */ 7390 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7391 orntNew[0] = -4; 7392 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 7393 orntNew[1] = ornt[1]; 7394 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 7395 orntNew[2] = ornt[2]; 7396 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7397 orntNew[3] = -1; 7398 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 7399 orntNew[4] = ornt[4]; 7400 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7401 orntNew[5] = 1; 7402 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 7403 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 7404 #if defined(PETSC_USE_DEBUG) 7405 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); 7406 for (p = 0; p < 6; ++p) { 7407 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); 7408 } 7409 #endif 7410 /* G hex */ 7411 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7412 orntNew[0] = -4; 7413 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 7414 orntNew[1] = ornt[1]; 7415 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7416 orntNew[2] = 0; 7417 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 7418 orntNew[3] = ornt[3]; 7419 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 7420 orntNew[4] = ornt[4]; 7421 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7422 orntNew[5] = -3; 7423 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 7424 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 7425 #if defined(PETSC_USE_DEBUG) 7426 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); 7427 for (p = 0; p < 6; ++p) { 7428 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); 7429 } 7430 #endif 7431 /* H hex */ 7432 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7433 orntNew[0] = -4; 7434 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 7435 orntNew[1] = ornt[1]; 7436 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7437 orntNew[2] = -1; 7438 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 7439 orntNew[3] = ornt[3]; 7440 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7441 orntNew[4] = 3; 7442 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 7443 orntNew[5] = ornt[5]; 7444 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 7445 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 7446 #if defined(PETSC_USE_DEBUG) 7447 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); 7448 for (p = 0; p < 6; ++p) { 7449 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); 7450 } 7451 #endif 7452 } 7453 /* Hybrid cells have 6 faces: Front, Back, Sides */ 7454 /* 7455 3---------2---------2 7456 | | | 7457 | D 2 C | 7458 | | | 7459 3----3----0----1----1 7460 | | | 7461 | A 0 B | 7462 | | | 7463 0---------0---------1 7464 */ 7465 for (c = cMax; c < cEnd; ++c) { 7466 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 7467 const PetscInt *cone, *ornt, *fornt; 7468 PetscInt coneNew[6], orntNew[6], o, of, i; 7469 7470 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7471 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7472 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 7473 o = ornt[0] < 0 ? -1 : 1; 7474 for (r = 0; r < 4; ++r) { 7475 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 7476 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 7477 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 7478 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]); 7479 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 7480 orntNew[0] = ornt[0]; 7481 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 7482 orntNew[1] = ornt[0]; 7483 of = fornt[edgeA] < 0 ? -1 : 1; 7484 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 7485 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 7486 orntNew[i] = ornt[edgeA]; 7487 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 7488 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 7489 orntNew[i] = 0; 7490 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 7491 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 7492 orntNew[i] = -2; 7493 of = fornt[edgeB] < 0 ? -1 : 1; 7494 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 7495 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 7496 orntNew[i] = ornt[edgeB]; 7497 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7498 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7499 #if defined(PETSC_USE_DEBUG) 7500 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); 7501 for (p = 0; p < 2; ++p) { 7502 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); 7503 } 7504 for (p = 2; p < 6; ++p) { 7505 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); 7506 } 7507 #endif 7508 } 7509 } 7510 /* Interior split faces have 4 edges and the same cells as the parent */ 7511 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7512 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 7513 for (f = fStart; f < fMax; ++f) { 7514 for (r = 0; r < 4; ++r) { 7515 /* TODO: This can come from GetFaces_Internal() */ 7516 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}; 7517 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 7518 const PetscInt *cone, *ornt, *support; 7519 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 7520 7521 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7522 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7523 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 7524 orntNew[(r+3)%4] = ornt[(r+3)%4]; 7525 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 7526 orntNew[(r+0)%4] = ornt[r]; 7527 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7528 orntNew[(r+1)%4] = 0; 7529 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 7530 orntNew[(r+2)%4] = -2; 7531 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7532 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7533 #if defined(PETSC_USE_DEBUG) 7534 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7535 for (p = 0; p < 4; ++p) { 7536 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); 7537 } 7538 #endif 7539 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7540 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7541 for (s = 0; s < supportSize; ++s) { 7542 PetscInt subf; 7543 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7544 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7545 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7546 for (c = 0; c < coneSize; ++c) { 7547 if (cone[c] == f) break; 7548 } 7549 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 7550 if (support[s] < cMax) { 7551 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 7552 } else { 7553 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 7554 } 7555 } 7556 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7557 #if defined(PETSC_USE_DEBUG) 7558 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7559 for (p = 0; p < supportSize; ++p) { 7560 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); 7561 } 7562 #endif 7563 } 7564 } 7565 /* Interior cell faces have 4 edges and 2 cells */ 7566 for (c = cStart; c < cMax; ++c) { 7567 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}; 7568 const PetscInt *cone, *ornt; 7569 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 7570 7571 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7572 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7573 /* A-D face */ 7574 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 7575 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 7576 orntNew[0] = 0; 7577 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7578 orntNew[1] = 0; 7579 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7580 orntNew[2] = -2; 7581 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 7582 orntNew[3] = -2; 7583 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7584 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7585 #if defined(PETSC_USE_DEBUG) 7586 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7587 for (p = 0; p < 4; ++p) { 7588 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); 7589 } 7590 #endif 7591 /* C-D face */ 7592 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 7593 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 7594 orntNew[0] = 0; 7595 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7596 orntNew[1] = 0; 7597 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7598 orntNew[2] = -2; 7599 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 7600 orntNew[3] = -2; 7601 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7602 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7603 #if defined(PETSC_USE_DEBUG) 7604 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7605 for (p = 0; p < 4; ++p) { 7606 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); 7607 } 7608 #endif 7609 /* B-C face */ 7610 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 7611 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 7612 orntNew[0] = -2; 7613 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 7614 orntNew[1] = 0; 7615 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7616 orntNew[2] = 0; 7617 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7618 orntNew[3] = -2; 7619 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7620 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7621 #if defined(PETSC_USE_DEBUG) 7622 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7623 for (p = 0; p < 4; ++p) { 7624 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); 7625 } 7626 #endif 7627 /* A-B face */ 7628 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 7629 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 7630 orntNew[0] = -2; 7631 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 7632 orntNew[1] = 0; 7633 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7634 orntNew[2] = 0; 7635 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7636 orntNew[3] = -2; 7637 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7638 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7639 #if defined(PETSC_USE_DEBUG) 7640 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7641 for (p = 0; p < 4; ++p) { 7642 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); 7643 } 7644 #endif 7645 /* E-F face */ 7646 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 7647 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7648 orntNew[0] = -2; 7649 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 7650 orntNew[1] = -2; 7651 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 7652 orntNew[2] = 0; 7653 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7654 orntNew[3] = 0; 7655 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7656 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7657 #if defined(PETSC_USE_DEBUG) 7658 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7659 for (p = 0; p < 4; ++p) { 7660 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); 7661 } 7662 #endif 7663 /* F-G face */ 7664 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 7665 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7666 orntNew[0] = -2; 7667 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 7668 orntNew[1] = -2; 7669 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 7670 orntNew[2] = 0; 7671 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7672 orntNew[3] = 0; 7673 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7674 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7675 #if defined(PETSC_USE_DEBUG) 7676 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7677 for (p = 0; p < 4; ++p) { 7678 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); 7679 } 7680 #endif 7681 /* G-H face */ 7682 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 7683 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 7684 orntNew[0] = -2; 7685 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 7686 orntNew[1] = 0; 7687 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7688 orntNew[2] = 0; 7689 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7690 orntNew[3] = -2; 7691 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7692 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7693 #if defined(PETSC_USE_DEBUG) 7694 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7695 for (p = 0; p < 4; ++p) { 7696 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eMaxNew); 7697 } 7698 #endif 7699 /* E-H face */ 7700 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 7701 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7702 orntNew[0] = -2; 7703 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 7704 orntNew[1] = -2; 7705 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 7706 orntNew[2] = 0; 7707 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7708 orntNew[3] = 0; 7709 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7710 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7711 #if defined(PETSC_USE_DEBUG) 7712 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7713 for (p = 0; p < 4; ++p) { 7714 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); 7715 } 7716 #endif 7717 /* A-E face */ 7718 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 7719 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 7720 orntNew[0] = 0; 7721 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7722 orntNew[1] = 0; 7723 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7724 orntNew[2] = -2; 7725 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 7726 orntNew[3] = -2; 7727 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7728 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7729 #if defined(PETSC_USE_DEBUG) 7730 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7731 for (p = 0; p < 4; ++p) { 7732 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); 7733 } 7734 #endif 7735 /* D-F face */ 7736 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 7737 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7738 orntNew[0] = -2; 7739 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7740 orntNew[1] = 0; 7741 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7742 orntNew[2] = 0; 7743 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7744 orntNew[3] = -2; 7745 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7746 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7747 #if defined(PETSC_USE_DEBUG) 7748 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7749 for (p = 0; p < 4; ++p) { 7750 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); 7751 } 7752 #endif 7753 /* C-G face */ 7754 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 7755 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7756 orntNew[0] = -2; 7757 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7758 orntNew[1] = -2; 7759 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7760 orntNew[2] = 0; 7761 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7762 orntNew[3] = 0; 7763 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7764 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7765 #if defined(PETSC_USE_DEBUG) 7766 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7767 for (p = 0; p < 4; ++p) { 7768 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); 7769 } 7770 #endif 7771 /* B-H face */ 7772 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 7773 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7774 orntNew[0] = 0; 7775 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7776 orntNew[1] = -2; 7777 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7778 orntNew[2] = -2; 7779 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7780 orntNew[3] = 0; 7781 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7782 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7783 #if defined(PETSC_USE_DEBUG) 7784 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7785 for (p = 0; p < 4; ++p) { 7786 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); 7787 } 7788 #endif 7789 for (r = 0; r < 12; ++r) { 7790 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 7791 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7792 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7793 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7794 #if defined(PETSC_USE_DEBUG) 7795 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7796 for (p = 0; p < 2; ++p) { 7797 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); 7798 } 7799 #endif 7800 } 7801 } 7802 /* Hybrid split faces have 4 edges and same cells */ 7803 for (f = fMax; f < fEnd; ++f) { 7804 const PetscInt *cone, *ornt, *support; 7805 PetscInt coneNew[4], orntNew[4]; 7806 PetscInt supportNew[2], size, s, c; 7807 7808 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7809 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7810 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7811 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7812 for (r = 0; r < 2; ++r) { 7813 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 7814 7815 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 7816 orntNew[0] = ornt[0]; 7817 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 7818 orntNew[1] = ornt[1]; 7819 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 7820 orntNew[2+r] = 0; 7821 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7822 orntNew[3-r] = 0; 7823 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7824 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7825 #if defined(PETSC_USE_DEBUG) 7826 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7827 for (p = 0; p < 2; ++p) { 7828 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); 7829 } 7830 for (p = 2; p < 4; ++p) { 7831 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); 7832 } 7833 #endif 7834 for (s = 0; s < size; ++s) { 7835 const PetscInt *coneCell, *orntCell, *fornt; 7836 PetscInt o, of; 7837 7838 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7839 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7840 o = orntCell[0] < 0 ? -1 : 1; 7841 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 7842 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 7843 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 7844 of = fornt[c-2] < 0 ? -1 : 1; 7845 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 7846 } 7847 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7848 #if defined(PETSC_USE_DEBUG) 7849 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7850 for (p = 0; p < size; ++p) { 7851 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); 7852 } 7853 #endif 7854 } 7855 } 7856 /* Hybrid cell faces have 4 edges and 2 cells */ 7857 for (c = cMax; c < cEnd; ++c) { 7858 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 7859 const PetscInt *cone, *ornt; 7860 PetscInt coneNew[4], orntNew[4]; 7861 PetscInt supportNew[2]; 7862 7863 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7864 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7865 for (r = 0; r < 4; ++r) { 7866 #if 0 7867 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 7868 orntNew[0] = 0; 7869 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 7870 orntNew[1] = 0; 7871 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 7872 orntNew[2] = 0; 7873 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7874 orntNew[3] = 0; 7875 #else 7876 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 7877 orntNew[0] = 0; 7878 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 7879 orntNew[1] = 0; 7880 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 7881 orntNew[2] = 0; 7882 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7883 orntNew[3] = 0; 7884 #endif 7885 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7886 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7887 #if defined(PETSC_USE_DEBUG) 7888 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); 7889 for (p = 0; p < 2; ++p) { 7890 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); 7891 } 7892 for (p = 2; p < 4; ++p) { 7893 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); 7894 } 7895 #endif 7896 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 7897 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 7898 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 7899 #if defined(PETSC_USE_DEBUG) 7900 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); 7901 for (p = 0; p < 2; ++p) { 7902 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); 7903 } 7904 #endif 7905 } 7906 } 7907 /* Interior split edges have 2 vertices and the same faces as the parent */ 7908 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7909 for (e = eStart; e < eMax; ++e) { 7910 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7911 7912 for (r = 0; r < 2; ++r) { 7913 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7914 const PetscInt *cone, *ornt, *support; 7915 PetscInt coneNew[2], coneSize, c, supportSize, s; 7916 7917 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7918 coneNew[0] = vStartNew + (cone[0] - vStart); 7919 coneNew[1] = vStartNew + (cone[1] - vStart); 7920 coneNew[(r+1)%2] = newv; 7921 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7922 #if defined(PETSC_USE_DEBUG) 7923 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7924 for (p = 0; p < 2; ++p) { 7925 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); 7926 } 7927 #endif 7928 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7929 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7930 for (s = 0; s < supportSize; ++s) { 7931 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7932 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7933 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7934 for (c = 0; c < coneSize; ++c) { 7935 if (cone[c] == e) break; 7936 } 7937 if (support[s] < fMax) { 7938 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 7939 } else { 7940 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 7941 } 7942 } 7943 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7944 #if defined(PETSC_USE_DEBUG) 7945 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7946 for (p = 0; p < supportSize; ++p) { 7947 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); 7948 } 7949 #endif 7950 } 7951 } 7952 /* Interior face edges have 2 vertices and 2+cells faces */ 7953 for (f = fStart; f < fMax; ++f) { 7954 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}; 7955 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 7956 const PetscInt *cone, *coneCell, *orntCell, *support; 7957 PetscInt coneNew[2], coneSize, c, supportSize, s; 7958 7959 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7960 for (r = 0; r < 4; ++r) { 7961 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7962 7963 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7964 coneNew[1] = newv; 7965 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7966 #if defined(PETSC_USE_DEBUG) 7967 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7968 for (p = 0; p < 2; ++p) { 7969 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); 7970 } 7971 #endif 7972 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7973 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7974 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7975 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7976 for (s = 0; s < supportSize; ++s) { 7977 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7978 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7979 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7980 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7981 if (support[s] < cMax) { 7982 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7983 } else { 7984 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 7985 } 7986 } 7987 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7988 #if defined(PETSC_USE_DEBUG) 7989 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7990 for (p = 0; p < 2+supportSize; ++p) { 7991 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); 7992 } 7993 #endif 7994 } 7995 } 7996 /* Interior cell edges have 2 vertices and 4 faces */ 7997 for (c = cStart; c < cMax; ++c) { 7998 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}; 7999 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 8000 const PetscInt *cone; 8001 PetscInt coneNew[2], supportNew[4]; 8002 8003 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8004 for (r = 0; r < 6; ++r) { 8005 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8006 8007 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 8008 coneNew[1] = newv; 8009 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8010 #if defined(PETSC_USE_DEBUG) 8011 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 8012 for (p = 0; p < 2; ++p) { 8013 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); 8014 } 8015 #endif 8016 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 8017 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8018 #if defined(PETSC_USE_DEBUG) 8019 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 8020 for (p = 0; p < 4; ++p) { 8021 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); 8022 } 8023 #endif 8024 } 8025 } 8026 /* Hybrid edges have two vertices and the same faces */ 8027 for (e = eMax; e < eEnd; ++e) { 8028 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 8029 const PetscInt *cone, *support, *fcone; 8030 PetscInt coneNew[2], size, fsize, s; 8031 8032 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8033 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8034 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8035 coneNew[0] = vStartNew + (cone[0] - vStart); 8036 coneNew[1] = vStartNew + (cone[1] - vStart); 8037 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8038 #if defined(PETSC_USE_DEBUG) 8039 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8040 for (p = 0; p < 2; ++p) { 8041 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); 8042 } 8043 #endif 8044 for (s = 0; s < size; ++s) { 8045 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 8046 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 8047 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 8048 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 8049 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 8050 } 8051 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8052 #if defined(PETSC_USE_DEBUG) 8053 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8054 for (p = 0; p < size; ++p) { 8055 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); 8056 } 8057 #endif 8058 } 8059 /* Hybrid face edges have 2 vertices and 2+cells faces */ 8060 for (f = fMax; f < fEnd; ++f) { 8061 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 8062 const PetscInt *cone, *support, *ccone, *cornt; 8063 PetscInt coneNew[2], size, csize, s; 8064 8065 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 8066 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8067 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8068 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 8069 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 8070 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8071 #if defined(PETSC_USE_DEBUG) 8072 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8073 for (p = 0; p < 2; ++p) { 8074 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); 8075 } 8076 #endif 8077 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 8078 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 8079 for (s = 0; s < size; ++s) { 8080 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 8081 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 8082 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 8083 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 8084 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]); 8085 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 8086 } 8087 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8088 #if defined(PETSC_USE_DEBUG) 8089 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8090 for (p = 0; p < 2+size; ++p) { 8091 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); 8092 } 8093 #endif 8094 } 8095 /* Hybrid cell edges have 2 vertices and 4 faces */ 8096 for (c = cMax; c < cEnd; ++c) { 8097 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 8098 const PetscInt *cone, *support; 8099 PetscInt coneNew[2], size; 8100 8101 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8102 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 8103 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 8104 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 8105 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 8106 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8107 #if defined(PETSC_USE_DEBUG) 8108 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8109 for (p = 0; p < 2; ++p) { 8110 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); 8111 } 8112 #endif 8113 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 8114 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 8115 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 8116 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 8117 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8118 #if defined(PETSC_USE_DEBUG) 8119 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8120 for (p = 0; p < 4; ++p) { 8121 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); 8122 } 8123 #endif 8124 } 8125 /* Interior vertices have identical supports */ 8126 for (v = vStart; v < vEnd; ++v) { 8127 const PetscInt newp = vStartNew + (v - vStart); 8128 const PetscInt *support, *cone; 8129 PetscInt size, s; 8130 8131 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 8132 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 8133 for (s = 0; s < size; ++s) { 8134 PetscInt r = 0; 8135 8136 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8137 if (cone[1] == v) r = 1; 8138 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 8139 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 8140 } 8141 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8142 #if defined(PETSC_USE_DEBUG) 8143 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8144 for (p = 0; p < size; ++p) { 8145 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); 8146 } 8147 #endif 8148 } 8149 /* Interior edge vertices have 2 + faces supports */ 8150 for (e = eStart; e < eMax; ++e) { 8151 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 8152 const PetscInt *cone, *support; 8153 PetscInt size, s; 8154 8155 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8156 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8157 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 8158 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 8159 for (s = 0; s < size; ++s) { 8160 PetscInt r; 8161 8162 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8163 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 8164 if (support[s] < fMax) { 8165 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 8166 } else { 8167 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 8168 } 8169 } 8170 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8171 #if defined(PETSC_USE_DEBUG) 8172 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8173 for (p = 0; p < 2+size; ++p) { 8174 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); 8175 } 8176 #endif 8177 } 8178 /* Interior face vertices have 4 + cells supports */ 8179 for (f = fStart; f < fMax; ++f) { 8180 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8181 const PetscInt *cone, *support; 8182 PetscInt size, s; 8183 8184 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8185 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8186 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 8187 for (s = 0; s < size; ++s) { 8188 PetscInt r; 8189 8190 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8191 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 8192 if (support[s] < cMax) { 8193 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 8194 } else { 8195 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 8196 } 8197 } 8198 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8199 #if defined(PETSC_USE_DEBUG) 8200 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8201 for (p = 0; p < 4+size; ++p) { 8202 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); 8203 } 8204 #endif 8205 } 8206 /* Cell vertices have 6 supports */ 8207 for (c = cStart; c < cMax; ++c) { 8208 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 8209 PetscInt supportNew[6]; 8210 8211 for (r = 0; r < 6; ++r) { 8212 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8213 } 8214 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8215 } 8216 ierr = PetscFree(supportRef);CHKERRQ(ierr); 8217 break; 8218 default: 8219 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8220 } 8221 PetscFunctionReturn(0); 8222 } 8223 8224 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8225 { 8226 PetscSection coordSection, coordSectionNew; 8227 Vec coordinates, coordinatesNew; 8228 PetscScalar *coords, *coordsNew; 8229 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 8230 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 8231 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 8232 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 8233 VecType vtype; 8234 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 8235 const PetscReal *maxCell, *L; 8236 const DMBoundaryType *bd; 8237 PetscErrorCode ierr; 8238 8239 PetscFunctionBegin; 8240 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8241 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8242 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8243 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8244 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8245 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8246 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 8247 if (cMax < 0) cMax = cEnd; 8248 if (fMax < 0) fMax = fEnd; 8249 if (eMax < 0) eMax = eEnd; 8250 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 8251 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 8252 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 8253 /* Determine if we need to localize coordinates when generating them */ 8254 if (isperiodic && !maxCell) { 8255 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 8256 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 8257 } 8258 if (isperiodic) { 8259 ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr); 8260 ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr); 8261 ierr = PetscOptionsEnd();CHKERRQ(ierr); 8262 if (localize) { 8263 ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 8264 } 8265 } 8266 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 8267 8268 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 8269 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 8270 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 8271 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 8272 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 8273 8274 if (localize) { 8275 PetscInt p, r, newp, *pi; 8276 8277 /* New coordinates will be already localized on the cell */ 8278 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 8279 8280 /* We need the parentId to properly localize coordinates */ 8281 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 8282 switch (refiner) { 8283 case REFINER_NOOP: 8284 break; 8285 case REFINER_SIMPLEX_1D: 8286 for (p = cStart; p < cEnd; ++p) { 8287 for (r = 0; r < 2; ++r) { 8288 newp = (p - cStart)*2 + r; 8289 pi[newp] = p; 8290 } 8291 } 8292 break; 8293 case REFINER_SIMPLEX_2D: 8294 for (p = cStart; p < cEnd; ++p) { 8295 for (r = 0; r < 4; ++r) { 8296 newp = (p - cStart)*4 + r; 8297 pi[newp] = p; 8298 } 8299 } 8300 break; 8301 case REFINER_HEX_2D: 8302 for (p = cStart; p < cEnd; ++p) { 8303 for (r = 0; r < 4; ++r) { 8304 newp = (p - cStart)*4 + r; 8305 pi[newp] = p; 8306 } 8307 } 8308 break; 8309 case REFINER_SIMPLEX_TO_HEX_2D: 8310 for (p = cStart; p < cEnd; ++p) { 8311 for (r = 0; r < 3; ++r) { 8312 newp = (p - cStart)*3 + r; 8313 pi[newp] = p; 8314 } 8315 } 8316 break; 8317 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8318 for (p = cStart; p < cMax; ++p) { 8319 for (r = 0; r < 3; ++r) { 8320 newp = (p - cStart)*3 + r; 8321 pi[newp] = p; 8322 } 8323 } 8324 for (p = cMax; p < cEnd; ++p) { 8325 for (r = 0; r < 4; ++r) { 8326 newp = (cMax - cStart)*3 + (p - cMax)*4 + r; 8327 pi[newp] = p; 8328 } 8329 } 8330 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8331 cMax = cEnd; 8332 eMax = eEnd; 8333 break; 8334 case REFINER_HYBRID_SIMPLEX_2D: 8335 for (p = cStart; p < cMax; ++p) { 8336 for (r = 0; r < 4; ++r) { 8337 newp = (p - cStart)*4 + r; 8338 pi[newp] = p; 8339 } 8340 } 8341 for (p = cMax; p < cEnd; ++p) { 8342 for (r = 0; r < 2; ++r) { 8343 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8344 pi[newp] = p; 8345 } 8346 } 8347 break; 8348 case REFINER_HYBRID_HEX_2D: 8349 for (p = cStart; p < cMax; ++p) { 8350 for (r = 0; r < 4; ++r) { 8351 newp = (p - cStart)*4 + r; 8352 pi[newp] = p; 8353 } 8354 } 8355 for (p = cMax; p < cEnd; ++p) { 8356 for (r = 0; r < 2; ++r) { 8357 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8358 pi[newp] = p; 8359 } 8360 } 8361 break; 8362 case REFINER_SIMPLEX_3D: 8363 for (p = cStart; p < cEnd; ++p) { 8364 for (r = 0; r < 8; ++r) { 8365 newp = (p - cStart)*8 + r; 8366 pi[newp] = p; 8367 } 8368 } 8369 break; 8370 case REFINER_HYBRID_SIMPLEX_3D: 8371 for (p = cStart; p < cMax; ++p) { 8372 for (r = 0; r < 8; ++r) { 8373 newp = (p - cStart)*8 + r; 8374 pi[newp] = p; 8375 } 8376 } 8377 for (p = cMax; p < cEnd; ++p) { 8378 for (r = 0; r < 4; ++r) { 8379 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8380 pi[newp] = p; 8381 } 8382 } 8383 break; 8384 case REFINER_SIMPLEX_TO_HEX_3D: 8385 for (p = cStart; p < cEnd; ++p) { 8386 for (r = 0; r < 4; ++r) { 8387 newp = (p - cStart)*4 + r; 8388 pi[newp] = p; 8389 } 8390 } 8391 break; 8392 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8393 for (p = cStart; p < cMax; ++p) { 8394 for (r = 0; r < 4; ++r) { 8395 newp = (p - cStart)*4 + r; 8396 pi[newp] = p; 8397 } 8398 } 8399 for (p = cMax; p < cEnd; ++p) { 8400 for (r = 0; r < 3; ++r) { 8401 newp = (cMax - cStart)*4 + (p - cMax)*3 + r; 8402 pi[newp] = p; 8403 } 8404 } 8405 break; 8406 case REFINER_HEX_3D: 8407 for (p = cStart; p < cEnd; ++p) { 8408 for (r = 0; r < 8; ++r) { 8409 newp = (p - cStart)*8 + r; 8410 pi[newp] = p; 8411 } 8412 } 8413 break; 8414 case REFINER_HYBRID_HEX_3D: 8415 for (p = cStart; p < cMax; ++p) { 8416 for (r = 0; r < 8; ++r) { 8417 newp = (p - cStart)*8 + r; 8418 pi[newp] = p; 8419 } 8420 } 8421 for (p = cMax; p < cEnd; ++p) { 8422 for (r = 0; r < 4; ++r) { 8423 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8424 pi[newp] = p; 8425 } 8426 } 8427 break; 8428 default: 8429 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8430 } 8431 parentId = pi; 8432 } else { 8433 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8434 if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; } 8435 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 8436 } 8437 8438 /* All vertices have the spaceDim coordinates */ 8439 if (localize) { 8440 PetscInt c; 8441 8442 for (c = cStartNew; c < cEndNew; ++c) { 8443 PetscInt *cone = NULL; 8444 PetscInt closureSize, coneSize = 0, p, pdof; 8445 8446 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 8447 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 8448 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8449 for (p = 0; p < closureSize*2; p += 2) { 8450 const PetscInt point = cone[p]; 8451 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 8452 } 8453 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8454 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 8455 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 8456 } 8457 } 8458 } 8459 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 8460 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 8461 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 8462 } 8463 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 8464 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 8465 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8466 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 8467 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 8468 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 8469 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 8470 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 8471 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 8472 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 8473 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 8474 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 8475 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8476 8477 switch (refiner) { 8478 case REFINER_NOOP: break; 8479 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8480 case REFINER_SIMPLEX_TO_HEX_3D: 8481 case REFINER_HEX_3D: 8482 case REFINER_HYBRID_HEX_3D: 8483 /* Face vertices have the average of corner coordinates */ 8484 for (f = fStart; f < fMax; ++f) { 8485 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8486 PetscInt *cone = NULL; 8487 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 8488 8489 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8490 for (p = 0; p < closureSize*2; p += 2) { 8491 const PetscInt point = cone[p]; 8492 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8493 } 8494 if (localize) { 8495 const PetscInt *support = NULL; 8496 PetscInt *rStar = NULL; 8497 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 8498 PetscBool cellfound = PETSC_FALSE; 8499 8500 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8501 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 8502 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 8503 /* Compute average of coordinates for each cell sharing the face */ 8504 for (s = 0; s < supportSize; ++s) { 8505 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 8506 PetscInt *cellCone = NULL; 8507 PetscInt cellClosureSize, cellConeSize = 0, cdof; 8508 const PetscInt cell = support[s]; 8509 PetscBool copyoff = PETSC_FALSE; 8510 8511 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8512 for (p = 0; p < cellClosureSize*2; p += 2) { 8513 const PetscInt point = cellCone[p]; 8514 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 8515 } 8516 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8517 if (!cdof) { /* the parent cell does not have localized coordinates */ 8518 cellfound = PETSC_TRUE; 8519 for (v = 0; v < coneSize; ++v) { 8520 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8521 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 8522 } 8523 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8524 } else { 8525 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8526 for (p = 0; p < coneSize; ++p) { 8527 const PetscInt tv = cone[p]; 8528 PetscInt cv, voff; 8529 PetscBool locv = PETSC_TRUE; 8530 8531 for (cv = 0; cv < cellConeSize; ++cv) { 8532 if (cellCone[cv] == tv) { 8533 ccoff[p] = spaceDim*cv + coff; 8534 break; 8535 } 8536 } 8537 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D",tv); 8538 8539 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 8540 for (d = 0; d < spaceDim; ++d) { 8541 coordsNewAux[d] += coords[ccoff[p]+d]; 8542 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 8543 } 8544 if (locv && !cellfound) { 8545 cellfound = PETSC_TRUE; 8546 copyoff = PETSC_TRUE; 8547 } 8548 } 8549 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8550 8551 /* Found a valid face for the "vertex" part of the Section (physical space) 8552 i.e., a face that has at least one corner in the physical space */ 8553 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 8554 } 8555 8556 /* Localize new coordinates on each refined cell */ 8557 for (v = 0; v < rStarSize*2; v += 2) { 8558 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 8559 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 8560 const PetscInt rcell = rStar[v]; 8561 8562 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8563 if (!rcdof) continue; 8564 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 8565 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8566 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8567 if (rcone[p] == newv) { 8568 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 8569 break; 8570 } 8571 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8572 } 8573 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8574 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8575 } 8576 } 8577 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8578 } 8579 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8580 if (!cellfound) { 8581 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 8582 needcoords = PETSC_TRUE; 8583 coneSize = 0; 8584 } 8585 } else { 8586 for (v = 0; v < coneSize; ++v) { 8587 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8588 } 8589 } 8590 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8591 if (coneSize) { 8592 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8593 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8594 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8595 } else { 8596 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8597 } 8598 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8599 } 8600 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8601 case REFINER_SIMPLEX_TO_HEX_2D: 8602 case REFINER_HEX_2D: 8603 case REFINER_HYBRID_HEX_2D: 8604 case REFINER_SIMPLEX_1D: 8605 /* Cell vertices have the average of corner coordinates */ 8606 for (c = cStart; c < cMax; ++c) { 8607 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 8608 PetscInt *cone = NULL; 8609 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 8610 8611 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8612 for (p = 0; p < closureSize*2; p += 2) { 8613 const PetscInt point = cone[p]; 8614 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8615 } 8616 if (localize) { 8617 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 8618 } 8619 if (cdof) { 8620 PetscInt coff; 8621 8622 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 8623 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 8624 } else { 8625 for (v = 0; v < coneSize; ++v) { 8626 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8627 } 8628 } 8629 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8630 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8631 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8632 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8633 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8634 8635 /* Localize new coordinates on each refined cell */ 8636 if (cdof) { 8637 PetscInt *rStar = NULL, rStarSize; 8638 8639 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8640 for (v = 0; v < rStarSize*2; v += 2) { 8641 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 8642 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 8643 8644 rc = rStar[v]; 8645 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 8646 if (!rcdof) continue; 8647 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 8648 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8649 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 8650 if (cone[p] == newv) { 8651 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 8652 break; 8653 } 8654 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 8655 } 8656 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8657 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8658 } 8659 } 8660 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8661 } 8662 } 8663 case REFINER_SIMPLEX_2D: 8664 case REFINER_HYBRID_SIMPLEX_2D: 8665 case REFINER_SIMPLEX_3D: 8666 case REFINER_HYBRID_SIMPLEX_3D: 8667 /* Edge vertices have the average of endpoint coordinates */ 8668 for (e = eStart; e < eMax; ++e) { 8669 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 8670 const PetscInt *cone; 8671 PetscInt coneSize, offA, offB, offnew, d; 8672 8673 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 8674 if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 8675 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8676 if (localize) { 8677 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 8678 PetscInt *eStar = NULL, eStarSize; 8679 PetscInt *rStar = NULL, rStarSize; 8680 PetscBool cellfound = PETSC_FALSE; 8681 8682 offA = offB = -1; 8683 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 8684 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 8685 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8686 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8687 for (v = 0; v < eStarSize*2; v += 2) { 8688 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 8689 PetscScalar coordsNewAux[3] = {0., 0., 0.}; 8690 PetscInt *cellCone = NULL; 8691 PetscInt cellClosureSize, s, cv, cdof; 8692 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 8693 const PetscInt cell = eStar[v]; 8694 8695 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8696 if (!cdof) { 8697 /* Found a valid edge for the "vertex" part of the Section */ 8698 offA = voffA; 8699 offB = voffB; 8700 cellfound = PETSC_TRUE; 8701 } else { 8702 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8703 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8704 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 8705 const PetscInt point = cellCone[s]; 8706 if ((point >= vStart) && (point < vEnd)) { 8707 if (point == cone[0]) toffA = spaceDim*cv + coff; 8708 else if (point == cone[1]) toffB = spaceDim*cv + coff; 8709 cv++; 8710 } 8711 } 8712 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8713 for (d = 0; d < spaceDim; ++d) { 8714 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 8715 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 8716 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 8717 } 8718 /* Found a valid edge for the "vertex" part of the Section */ 8719 if (!cellfound && (locvA || locvB)) { 8720 cellfound = PETSC_TRUE; 8721 offA = toffA; 8722 offB = toffB; 8723 } 8724 } 8725 8726 /* Localize new coordinates on each refined cell */ 8727 for (s = 0; s < rStarSize*2; s += 2) { 8728 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 8729 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 8730 const PetscInt rcell = rStar[s]; 8731 8732 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8733 if (!rcdof) continue; 8734 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 8735 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8736 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8737 if (rcone[p] == newv) { 8738 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 8739 break; 8740 } 8741 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8742 } 8743 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8744 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8745 } 8746 } 8747 } 8748 } 8749 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8750 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8751 if (!cellfound) { 8752 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 8753 needcoords = PETSC_TRUE; 8754 } 8755 } else { 8756 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 8757 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 8758 } 8759 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8760 if (offA != -1 && offB != -1) { 8761 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 8762 for (d = 0; d < spaceDim; ++d) { 8763 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 8764 ierr = DMPlexSnapToGeomModel(dm, e, &coordsNew[offnew], &coordsNew[offnew]);CHKERRQ(ierr); 8765 } 8766 } else { 8767 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8768 } 8769 } 8770 /* Old vertices have the same coordinates */ 8771 for (v = vStart; v < vEnd; ++v) { 8772 const PetscInt newv = vStartNew + (v - vStart); 8773 PetscInt off, offnew, d; 8774 8775 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 8776 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8777 for (d = 0; d < spaceDim; ++d) { 8778 coordsNew[offnew+d] = coords[off+d]; 8779 } 8780 8781 /* Localize new coordinates on each refined cell */ 8782 if (localize) { 8783 PetscInt p; 8784 PetscInt *rStar = NULL, rStarSize; 8785 8786 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8787 for (p = 0; p < rStarSize*2; p += 2) { 8788 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 8789 PetscScalar ocoords[3] = {0,0,0}; /* dummy values for compiler warnings about uninitialized values */ 8790 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 8791 8792 c = rStar[p]; 8793 oc = parentId[c-cStartNew]; 8794 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 8795 if (!cdof) continue; 8796 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 8797 if (!cdof) continue; 8798 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 8799 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8800 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8801 if (cone[s] == v) { 8802 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 8803 break; 8804 } 8805 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 8806 } 8807 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D",v); 8808 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8809 8810 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 8811 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8812 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8813 if (cone[s] == newv) { 8814 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 8815 break; 8816 } 8817 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 8818 } 8819 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8820 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8821 } 8822 } 8823 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8824 } 8825 } 8826 break; 8827 default: 8828 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8829 } 8830 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 8831 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8832 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 8833 8834 /* Final reduction (if needed) if we are localizing */ 8835 if (localize) { 8836 PetscBool gred; 8837 8838 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 8839 if (gred) { 8840 DM cdm; 8841 Vec aux; 8842 PetscSF sf; 8843 const PetscScalar *lArray; 8844 PetscScalar *gArray; 8845 #if defined(PETSC_USE_COMPLEX) 8846 PetscInt i, ln, gn; 8847 PetscReal *lrArray; 8848 PetscReal *grArray; 8849 #endif 8850 8851 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 8852 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 8853 ierr = DMGetSectionSF(cdm, &sf);CHKERRQ(ierr); 8854 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8855 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 8856 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 8857 #if defined(PETSC_USE_COMPLEX) 8858 ierr = VecGetLocalSize(aux, &gn);CHKERRQ(ierr); 8859 ierr = VecGetLocalSize(coordinatesNew, &ln);CHKERRQ(ierr); 8860 ierr = PetscMalloc2(ln,&lrArray,gn,&grArray);CHKERRQ(ierr); 8861 for (i=0;i<ln;i++) lrArray[i] = PetscRealPart(lArray[i]); 8862 for (i=0;i<gn;i++) grArray[i] = PetscRealPart(gArray[i]); 8863 ierr = PetscSFReduceBegin(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8864 ierr = PetscSFReduceEnd(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8865 for (i=0;i<gn;i++) gArray[i] = grArray[i]; 8866 ierr = PetscFree2(lrArray,grArray);CHKERRQ(ierr); 8867 #else 8868 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8869 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8870 #endif 8871 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8872 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 8873 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8874 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8875 ierr = VecDestroy(&aux);CHKERRQ(ierr); 8876 } 8877 } 8878 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 8879 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 8880 ierr = PetscFree(parentId);CHKERRQ(ierr); 8881 PetscFunctionReturn(0); 8882 } 8883 8884 /*@ 8885 DMPlexCreateProcessSF - Create an SF which just has process connectivity 8886 8887 Collective on dm 8888 8889 Input Parameters: 8890 + dm - The DM 8891 - sfPoint - The PetscSF which encodes point connectivity 8892 8893 Output Parameters: 8894 + processRanks - A list of process neighbors, or NULL 8895 - sfProcess - An SF encoding the process connectivity, or NULL 8896 8897 Level: developer 8898 8899 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 8900 @*/ 8901 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 8902 { 8903 PetscInt numRoots, numLeaves, l; 8904 const PetscInt *localPoints; 8905 const PetscSFNode *remotePoints; 8906 PetscInt *localPointsNew; 8907 PetscSFNode *remotePointsNew; 8908 PetscInt *ranks, *ranksNew; 8909 PetscMPIInt size; 8910 PetscErrorCode ierr; 8911 8912 PetscFunctionBegin; 8913 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8914 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 8915 if (processRanks) {PetscValidPointer(processRanks, 3);} 8916 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 8917 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 8918 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8919 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 8920 for (l = 0; l < numLeaves; ++l) { 8921 ranks[l] = remotePoints[l].rank; 8922 } 8923 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 8924 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 8925 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 8926 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 8927 for (l = 0; l < numLeaves; ++l) { 8928 ranksNew[l] = ranks[l]; 8929 localPointsNew[l] = l; 8930 remotePointsNew[l].index = 0; 8931 remotePointsNew[l].rank = ranksNew[l]; 8932 } 8933 ierr = PetscFree(ranks);CHKERRQ(ierr); 8934 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 8935 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 8936 if (sfProcess) { 8937 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 8938 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 8939 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 8940 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 8941 } 8942 PetscFunctionReturn(0); 8943 } 8944 8945 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8946 { 8947 PetscSF sf, sfNew, sfProcess; 8948 IS processRanks; 8949 MPI_Datatype depthType; 8950 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 8951 const PetscInt *localPoints, *neighbors; 8952 const PetscSFNode *remotePoints; 8953 PetscInt *localPointsNew; 8954 PetscSFNode *remotePointsNew; 8955 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 8956 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 8957 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8958 PetscErrorCode ierr; 8959 8960 PetscFunctionBegin; 8961 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 8962 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 8963 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 8964 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %D != %D", ldepth, depth); 8965 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8966 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8967 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8968 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8969 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 8970 cMax = cMax < 0 ? cEnd : cMax; 8971 fMax = fMax < 0 ? fEnd : fMax; 8972 eMax = eMax < 0 ? eEnd : eMax; 8973 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8974 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 8975 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 8976 /* Calculate size of new SF */ 8977 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8978 if (numRoots < 0) PetscFunctionReturn(0); 8979 for (l = 0; l < numLeaves; ++l) { 8980 const PetscInt p = localPoints[l]; 8981 8982 switch (refiner) { 8983 case REFINER_SIMPLEX_1D: 8984 if ((p >= vStart) && (p < vEnd)) { 8985 /* Interior vertices stay the same */ 8986 ++numLeavesNew; 8987 } else if ((p >= cStart && p < cMax)) { 8988 /* Interior cells add new cells and interior vertices */ 8989 numLeavesNew += 2 + 1; 8990 } 8991 break; 8992 case REFINER_SIMPLEX_2D: 8993 case REFINER_HYBRID_SIMPLEX_2D: 8994 if ((p >= vStart) && (p < vEnd)) { 8995 /* Interior vertices stay the same */ 8996 ++numLeavesNew; 8997 } else if ((p >= fStart) && (p < fMax)) { 8998 /* Interior faces add new faces and vertex */ 8999 numLeavesNew += 2 + 1; 9000 } else if ((p >= fMax) && (p < fEnd)) { 9001 /* Hybrid faces stay the same */ 9002 ++numLeavesNew; 9003 } else if ((p >= cStart) && (p < cMax)) { 9004 /* Interior cells add new cells and interior faces */ 9005 numLeavesNew += 4 + 3; 9006 } else if ((p >= cMax) && (p < cEnd)) { 9007 /* Hybrid cells add new cells and hybrid face */ 9008 numLeavesNew += 2 + 1; 9009 } 9010 break; 9011 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9012 case REFINER_SIMPLEX_TO_HEX_2D: 9013 if ((p >= vStart) && (p < vEnd)) { 9014 /* Interior vertices stay the same */ 9015 ++numLeavesNew; 9016 } else if ((p >= fStart) && (p < fEnd)) { 9017 /* Interior faces add new faces and vertex */ 9018 numLeavesNew += 2 + 1; 9019 } else if ((p >= cStart) && (p < cMax)) { 9020 /* Interior cells add new cells, interior faces, and vertex */ 9021 numLeavesNew += 3 + 3 + 1; 9022 } else if ((p >= cMax) && (p < cEnd)) { 9023 /* Hybrid cells add new cells, interior faces, and vertex */ 9024 numLeavesNew += 4 + 4 + 1; 9025 } 9026 break; 9027 case REFINER_HEX_2D: 9028 case REFINER_HYBRID_HEX_2D: 9029 if ((p >= vStart) && (p < vEnd)) { 9030 /* Interior vertices stay the same */ 9031 ++numLeavesNew; 9032 } else if ((p >= fStart) && (p < fMax)) { 9033 /* Interior faces add new faces and vertex */ 9034 numLeavesNew += 2 + 1; 9035 } else if ((p >= fMax) && (p < fEnd)) { 9036 /* Hybrid faces stay the same */ 9037 ++numLeavesNew; 9038 } else if ((p >= cStart) && (p < cMax)) { 9039 /* Interior cells add new cells, interior faces, and vertex */ 9040 numLeavesNew += 4 + 4 + 1; 9041 } else if ((p >= cMax) && (p < cEnd)) { 9042 /* Hybrid cells add new cells and hybrid face */ 9043 numLeavesNew += 2 + 1; 9044 } 9045 break; 9046 case REFINER_SIMPLEX_3D: 9047 case REFINER_HYBRID_SIMPLEX_3D: 9048 if ((p >= vStart) && (p < vEnd)) { 9049 /* Interior vertices stay the same */ 9050 ++numLeavesNew; 9051 } else if ((p >= eStart) && (p < eMax)) { 9052 /* Interior edges add new edges and vertex */ 9053 numLeavesNew += 2 + 1; 9054 } else if ((p >= eMax) && (p < eEnd)) { 9055 /* Hybrid edges stay the same */ 9056 ++numLeavesNew; 9057 } else if ((p >= fStart) && (p < fMax)) { 9058 /* Interior faces add new faces and edges */ 9059 numLeavesNew += 4 + 3; 9060 } else if ((p >= fMax) && (p < fEnd)) { 9061 /* Hybrid faces add new faces and edges */ 9062 numLeavesNew += 2 + 1; 9063 } else if ((p >= cStart) && (p < cMax)) { 9064 /* Interior cells add new cells, faces, and edges */ 9065 numLeavesNew += 8 + 8 + 1; 9066 } else if ((p >= cMax) && (p < cEnd)) { 9067 /* Hybrid cells add new cells and faces */ 9068 numLeavesNew += 4 + 3; 9069 } 9070 break; 9071 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9072 case REFINER_SIMPLEX_TO_HEX_3D: 9073 if ((p >= vStart) && (p < vEnd)) { 9074 /* Interior vertices stay the same */ 9075 ++numLeavesNew; 9076 } else if ((p >= eStart) && (p < eMax)) { 9077 /* Interior edges add new edges and vertex */ 9078 numLeavesNew += 2 + 1; 9079 } else if ((p >= eMax) && (p < eEnd)) { 9080 /* Hybrid edges stay the same */ 9081 ++numLeavesNew; 9082 } else if ((p >= fStart) && (p < fMax)) { 9083 /* Interior faces add new faces, edges and a vertex */ 9084 numLeavesNew += 3 + 3 + 1; 9085 } else if ((p >= fMax) && (p < fEnd)) { 9086 /* Hybrid faces add new faces and an edge */ 9087 numLeavesNew += 2 + 1; 9088 } else if ((p >= cStart) && (p < cMax)) { 9089 /* Interior cells add new cells, faces, edges and a vertex */ 9090 numLeavesNew += 4 + 6 + 4 + 1; 9091 } else if ((p >= cMax) && (p < cEnd)) { 9092 /* Hybrid cells add new cells, faces and an edge */ 9093 numLeavesNew += 3 + 3 + 1; 9094 } 9095 break; 9096 case REFINER_HEX_3D: 9097 case REFINER_HYBRID_HEX_3D: 9098 if ((p >= vStart) && (p < vEnd)) { 9099 /* Old vertices stay the same */ 9100 ++numLeavesNew; 9101 } else if ((p >= eStart) && (p < eMax)) { 9102 /* Interior edges add new edges, and vertex */ 9103 numLeavesNew += 2 + 1; 9104 } else if ((p >= eMax) && (p < eEnd)) { 9105 /* Hybrid edges stay the same */ 9106 ++numLeavesNew; 9107 } else if ((p >= fStart) && (p < fMax)) { 9108 /* Interior faces add new faces, edges, and vertex */ 9109 numLeavesNew += 4 + 4 + 1; 9110 } else if ((p >= fMax) && (p < fEnd)) { 9111 /* Hybrid faces add new faces and edges */ 9112 numLeavesNew += 2 + 1; 9113 } else if ((p >= cStart) && (p < cMax)) { 9114 /* Interior cells add new cells, faces, edges, and vertex */ 9115 numLeavesNew += 8 + 12 + 6 + 1; 9116 } else if ((p >= cStart) && (p < cEnd)) { 9117 /* Hybrid cells add new cells, faces, and edges */ 9118 numLeavesNew += 4 + 4 + 1; 9119 } 9120 break; 9121 default: 9122 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9123 } 9124 } 9125 /* Communicate depthSizes for each remote rank */ 9126 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 9127 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 9128 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 9129 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 9130 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 9131 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 9132 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9133 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9134 for (n = 0; n < numNeighbors; ++n) { 9135 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 9136 } 9137 depthSizeOld[depth] = cMax; 9138 depthSizeOld[0] = vMax; 9139 depthSizeOld[depth-1] = fMax; 9140 depthSizeOld[1] = eMax; 9141 9142 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9143 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9144 9145 depthSizeOld[depth] = cEnd - cStart; 9146 depthSizeOld[0] = vEnd - vStart; 9147 depthSizeOld[depth-1] = fEnd - fStart; 9148 depthSizeOld[1] = eEnd - eStart; 9149 9150 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9151 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9152 for (n = 0; n < numNeighbors; ++n) { 9153 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 9154 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 9155 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]; 9156 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 9157 } 9158 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 9159 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 9160 /* Calculate new point SF */ 9161 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 9162 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 9163 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 9164 for (l = 0, m = 0; l < numLeaves; ++l) { 9165 PetscInt p = localPoints[l]; 9166 PetscInt rp = remotePoints[l].index, n; 9167 PetscMPIInt rrank = remotePoints[l].rank; 9168 9169 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 9170 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rrank); 9171 switch (refiner) { 9172 case REFINER_SIMPLEX_1D: 9173 if ((p >= vStart) && (p < vEnd)) { 9174 /* Old vertices stay the same */ 9175 localPointsNew[m] = vStartNew + (p - vStart); 9176 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9177 remotePointsNew[m].rank = rrank; 9178 ++m; 9179 } else if ((p >= cStart) && (p < cMax)) { 9180 /* Old interior cells add new cells and vertex */ 9181 for (r = 0; r < 2; ++r, ++m) { 9182 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 9183 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 9184 remotePointsNew[m].rank = rrank; 9185 } 9186 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 9187 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 9188 remotePointsNew[m].rank = rrank; 9189 ++m; 9190 } 9191 break; 9192 case REFINER_SIMPLEX_2D: 9193 case REFINER_HYBRID_SIMPLEX_2D: 9194 if ((p >= vStart) && (p < vEnd)) { 9195 /* Old vertices stay the same */ 9196 localPointsNew[m] = vStartNew + (p - vStart); 9197 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9198 remotePointsNew[m].rank = rrank; 9199 ++m; 9200 } else if ((p >= fStart) && (p < fMax)) { 9201 /* Old interior faces add new faces and vertex */ 9202 for (r = 0; r < 2; ++r, ++m) { 9203 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9204 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9205 remotePointsNew[m].rank = rrank; 9206 } 9207 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9208 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9209 remotePointsNew[m].rank = rrank; 9210 ++m; 9211 } else if ((p >= fMax) && (p < fEnd)) { 9212 /* Old hybrid faces stay the same */ 9213 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9214 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9215 remotePointsNew[m].rank = rrank; 9216 ++m; 9217 } else if ((p >= cStart) && (p < cMax)) { 9218 /* Old interior cells add new cells and interior faces */ 9219 for (r = 0; r < 4; ++r, ++m) { 9220 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9221 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9222 remotePointsNew[m].rank = rrank; 9223 } 9224 for (r = 0; r < 3; ++r, ++m) { 9225 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 9226 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 9227 remotePointsNew[m].rank = rrank; 9228 } 9229 } else if ((p >= cMax) && (p < cEnd)) { 9230 /* Old hybrid cells add new cells and hybrid face */ 9231 for (r = 0; r < 2; ++r, ++m) { 9232 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9233 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9234 remotePointsNew[m].rank = rrank; 9235 } 9236 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9237 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]); 9238 remotePointsNew[m].rank = rrank; 9239 ++m; 9240 } 9241 break; 9242 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9243 case REFINER_SIMPLEX_TO_HEX_2D: 9244 if ((p >= vStart) && (p < vEnd)) { 9245 /* Old vertices stay the same */ 9246 localPointsNew[m] = vStartNew + (p - vStart); 9247 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9248 remotePointsNew[m].rank = rrank; 9249 ++m; 9250 } else if ((p >= fStart) && (p < fEnd)) { 9251 /* Old interior faces add new faces and vertex */ 9252 for (r = 0; r < 2; ++r, ++m) { 9253 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9254 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9255 remotePointsNew[m].rank = rrank; 9256 } 9257 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9258 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9259 remotePointsNew[m].rank = rrank; 9260 ++m; 9261 } else if ((p >= cStart) && (p < cMax)) { 9262 /* Old interior cells add new cells, interior faces, and a vertex */ 9263 for (r = 0; r < 3; ++r, ++m) { 9264 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 9265 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 9266 remotePointsNew[m].rank = rrank; 9267 } 9268 for (r = 0; r < 3; ++r, ++m) { 9269 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9270 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 9271 remotePointsNew[m].rank = rrank; 9272 } 9273 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9274 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9275 remotePointsNew[m].rank = rrank; 9276 ++m; 9277 } else if ((p >= cMax) && (p < cEnd)) { 9278 /* Old interior hybrid cells add new cells, interior faces, and a vertex */ 9279 for (r = 0; r < 4; ++r, ++m) { 9280 localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9281 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9282 remotePointsNew[m].rank = rrank; 9283 } 9284 for (r = 0; r < 4; ++r, ++m) { 9285 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9286 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; 9287 remotePointsNew[m].rank = rrank; 9288 } 9289 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9290 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9291 remotePointsNew[m].rank = rrank; 9292 ++m; 9293 } 9294 break; 9295 case REFINER_HEX_2D: 9296 case REFINER_HYBRID_HEX_2D: 9297 if ((p >= vStart) && (p < vEnd)) { 9298 /* Old vertices stay the same */ 9299 localPointsNew[m] = vStartNew + (p - vStart); 9300 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9301 remotePointsNew[m].rank = rrank; 9302 ++m; 9303 } else if ((p >= fStart) && (p < fMax)) { 9304 /* Old interior faces add new faces and vertex */ 9305 for (r = 0; r < 2; ++r, ++m) { 9306 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9307 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9308 remotePointsNew[m].rank = rrank; 9309 } 9310 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9311 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9312 remotePointsNew[m].rank = rrank; 9313 ++m; 9314 } else if ((p >= fMax) && (p < fEnd)) { 9315 /* Old hybrid faces stay the same */ 9316 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9317 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9318 remotePointsNew[m].rank = rrank; 9319 ++m; 9320 } else if ((p >= cStart) && (p < cMax)) { 9321 /* Old interior cells add new cells, interior faces, and vertex */ 9322 for (r = 0; r < 4; ++r, ++m) { 9323 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9324 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9325 remotePointsNew[m].rank = rrank; 9326 } 9327 for (r = 0; r < 4; ++r, ++m) { 9328 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 9329 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 9330 remotePointsNew[m].rank = rrank; 9331 } 9332 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 9333 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 9334 remotePointsNew[m].rank = rrank; 9335 ++m; 9336 } else if ((p >= cStart) && (p < cMax)) { 9337 /* Old hybrid cells add new cells and hybrid face */ 9338 for (r = 0; r < 2; ++r, ++m) { 9339 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */ 9340 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */ 9341 remotePointsNew[m].rank = rrank; 9342 } 9343 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9344 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]); 9345 remotePointsNew[m].rank = rrank; 9346 ++m; 9347 } 9348 break; 9349 case REFINER_SIMPLEX_3D: 9350 case REFINER_HYBRID_SIMPLEX_3D: 9351 if ((p >= vStart) && (p < vEnd)) { 9352 /* Interior vertices stay the same */ 9353 localPointsNew[m] = vStartNew + (p - vStart); 9354 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9355 remotePointsNew[m].rank = rrank; 9356 ++m; 9357 } else if ((p >= eStart) && (p < eMax)) { 9358 /* Interior edges add new edges and vertex */ 9359 for (r = 0; r < 2; ++r, ++m) { 9360 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9361 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9362 remotePointsNew[m].rank = rrank; 9363 } 9364 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9365 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9366 remotePointsNew[m].rank = rrank; 9367 ++m; 9368 } else if ((p >= eMax) && (p < eEnd)) { 9369 /* Hybrid edges stay the same */ 9370 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9371 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]); 9372 remotePointsNew[m].rank = rrank; 9373 ++m; 9374 } else if ((p >= fStart) && (p < fMax)) { 9375 /* Interior faces add new faces and edges */ 9376 for (r = 0; r < 4; ++r, ++m) { 9377 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9378 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9379 remotePointsNew[m].rank = rrank; 9380 } 9381 for (r = 0; r < 3; ++r, ++m) { 9382 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9383 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9384 remotePointsNew[m].rank = rrank; 9385 } 9386 } else if ((p >= fMax) && (p < fEnd)) { 9387 /* Hybrid faces add new faces and edges */ 9388 for (r = 0; r < 2; ++r, ++m) { 9389 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9390 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; 9391 remotePointsNew[m].rank = rrank; 9392 } 9393 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 9394 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]); 9395 remotePointsNew[m].rank = rrank; 9396 ++m; 9397 } else if ((p >= cStart) && (p < cMax)) { 9398 /* Interior cells add new cells, faces, and edges */ 9399 for (r = 0; r < 8; ++r, ++m) { 9400 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9401 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9402 remotePointsNew[m].rank = rrank; 9403 } 9404 for (r = 0; r < 8; ++r, ++m) { 9405 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9406 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 9407 remotePointsNew[m].rank = rrank; 9408 } 9409 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 9410 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; 9411 remotePointsNew[m].rank = rrank; 9412 ++m; 9413 } else if ((p >= cMax) && (p < cEnd)) { 9414 /* Hybrid cells add new cells and faces */ 9415 for (r = 0; r < 4; ++r, ++m) { 9416 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9417 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9418 remotePointsNew[m].rank = rrank; 9419 } 9420 for (r = 0; r < 3; ++r, ++m) { 9421 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9422 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; 9423 remotePointsNew[m].rank = rrank; 9424 } 9425 } 9426 break; 9427 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9428 case REFINER_SIMPLEX_TO_HEX_3D: 9429 if ((p >= vStart) && (p < vEnd)) { 9430 /* Interior vertices stay the same */ 9431 localPointsNew[m] = vStartNew + (p - vStart); 9432 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9433 remotePointsNew[m].rank = rrank; 9434 ++m; 9435 } else if ((p >= eStart) && (p < eMax)) { 9436 /* Interior edges add new edges and vertex */ 9437 for (r = 0; r < 2; ++r, ++m) { 9438 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9439 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9440 remotePointsNew[m].rank = rrank; 9441 } 9442 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9443 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9444 remotePointsNew[m].rank = rrank; 9445 ++m; 9446 } else if ((p >= eMax) && (p < eEnd)) { 9447 /* Hybrid edges stay the same */ 9448 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax); 9449 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]); 9450 remotePointsNew[m].rank = rrank; 9451 ++m; 9452 } else if ((p >= fStart) && (p < fMax)) { 9453 /* Interior faces add new faces, edges and a vertex */ 9454 for (r = 0; r < 3; ++r, ++m) { 9455 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 9456 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 9457 remotePointsNew[m].rank = rrank; 9458 } 9459 for (r = 0; r < 3; ++r, ++m) { 9460 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9461 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9462 remotePointsNew[m].rank = rrank; 9463 } 9464 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9465 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9466 remotePointsNew[m].rank = rrank; 9467 ++m; 9468 } else if ((p >= fMax) && (p < fEnd)) { 9469 /* Interior hybrid faces add new faces and an edge */ 9470 for (r = 0; r < 2; ++r, ++m) { 9471 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9472 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; 9473 remotePointsNew[m].rank = rrank; 9474 } 9475 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9476 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]); 9477 remotePointsNew[m].rank = rrank; 9478 ++m; 9479 } else if ((p >= cStart) && (p < cMax)) { 9480 /* Interior cells add new cells, faces, edges, and a vertex */ 9481 for (r = 0; r < 4; ++r, ++m) { 9482 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9483 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9484 remotePointsNew[m].rank = rrank; 9485 } 9486 for (r = 0; r < 6; ++r, ++m) { 9487 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9488 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r; 9489 remotePointsNew[m].rank = rrank; 9490 } 9491 for (r = 0; r < 4; ++r, ++m) { 9492 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9493 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; 9494 remotePointsNew[m].rank = rrank; 9495 } 9496 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 9497 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]); 9498 remotePointsNew[m].rank = rrank; 9499 ++m; 9500 } else if ((p >= cMax) && (p < cEnd)) { 9501 /* Interior hybrid cells add new cells, faces and an edge */ 9502 for (r = 0; r < 3; ++r, ++m) { 9503 localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9504 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9505 remotePointsNew[m].rank = rrank; 9506 } 9507 for (r = 0; r < 3; ++r, ++m) { 9508 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9509 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; 9510 remotePointsNew[m].rank = rrank; 9511 } 9512 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9513 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]); 9514 remotePointsNew[m].rank = rrank; 9515 ++m; 9516 } 9517 break; 9518 case REFINER_HEX_3D: 9519 case REFINER_HYBRID_HEX_3D: 9520 if ((p >= vStart) && (p < vEnd)) { 9521 /* Interior vertices stay the same */ 9522 localPointsNew[m] = vStartNew + (p - vStart); 9523 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9524 remotePointsNew[m].rank = rrank; 9525 ++m; 9526 } else if ((p >= eStart) && (p < eMax)) { 9527 /* Interior edges add new edges and vertex */ 9528 for (r = 0; r < 2; ++r, ++m) { 9529 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9530 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9531 remotePointsNew[m].rank = rrank; 9532 } 9533 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9534 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9535 remotePointsNew[m].rank = rrank; 9536 ++m; 9537 } else if ((p >= eMax) && (p < eEnd)) { 9538 /* Hybrid edges stay the same */ 9539 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 9540 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]); 9541 remotePointsNew[m].rank = rrank; 9542 ++m; 9543 } else if ((p >= fStart) && (p < fMax)) { 9544 /* Interior faces add new faces, edges, and vertex */ 9545 for (r = 0; r < 4; ++r, ++m) { 9546 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9547 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9548 remotePointsNew[m].rank = rrank; 9549 } 9550 for (r = 0; r < 4; ++r, ++m) { 9551 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 9552 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 9553 remotePointsNew[m].rank = rrank; 9554 } 9555 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9556 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9557 remotePointsNew[m].rank = rrank; 9558 ++m; 9559 } else if ((p >= fMax) && (p < fEnd)) { 9560 /* Hybrid faces add new faces and edges */ 9561 for (r = 0; r < 2; ++r, ++m) { 9562 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 9563 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; 9564 remotePointsNew[m].rank = rrank; 9565 } 9566 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 9567 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]); 9568 remotePointsNew[m].rank = rrank; 9569 ++m; 9570 } else if ((p >= cStart) && (p < cMax)) { 9571 /* Interior cells add new cells, faces, edges, and vertex */ 9572 for (r = 0; r < 8; ++r, ++m) { 9573 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9574 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9575 remotePointsNew[m].rank = rrank; 9576 } 9577 for (r = 0; r < 12; ++r, ++m) { 9578 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 9579 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 9580 remotePointsNew[m].rank = rrank; 9581 } 9582 for (r = 0; r < 6; ++r, ++m) { 9583 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 9584 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; 9585 remotePointsNew[m].rank = rrank; 9586 } 9587 for (r = 0; r < 1; ++r, ++m) { 9588 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 9589 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 9590 remotePointsNew[m].rank = rrank; 9591 } 9592 } else if ((p >= cMax) && (p < cEnd)) { 9593 /* Hybrid cells add new cells, faces, and edges */ 9594 for (r = 0; r < 4; ++r, ++m) { 9595 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9596 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9597 remotePointsNew[m].rank = rrank; 9598 } 9599 for (r = 0; r < 4; ++r, ++m) { 9600 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 9601 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; 9602 remotePointsNew[m].rank = rrank; 9603 } 9604 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9605 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]); 9606 remotePointsNew[m].rank = rrank; 9607 ++m; 9608 } 9609 break; 9610 default: 9611 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9612 } 9613 } 9614 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 9615 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 9616 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 9617 { 9618 PetscSFNode *rp, *rtmp; 9619 PetscInt *lp, *idx, *ltmp, i; 9620 9621 /* SF needs sorted leaves to correct calculate Gather */ 9622 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 9623 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 9624 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 9625 for (i = 0; i < numLeavesNew; ++i) { 9626 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); 9627 idx[i] = i; 9628 } 9629 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 9630 for (i = 0; i < numLeavesNew; ++i) { 9631 lp[i] = localPointsNew[idx[i]]; 9632 rp[i] = remotePointsNew[idx[i]]; 9633 } 9634 ltmp = localPointsNew; 9635 localPointsNew = lp; 9636 rtmp = remotePointsNew; 9637 remotePointsNew = rp; 9638 ierr = PetscFree(idx);CHKERRQ(ierr); 9639 ierr = PetscFree(ltmp);CHKERRQ(ierr); 9640 ierr = PetscFree(rtmp);CHKERRQ(ierr); 9641 } 9642 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 9643 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 9644 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 9645 PetscFunctionReturn(0); 9646 } 9647 9648 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 9649 { 9650 PetscInt numLabels, l; 9651 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 9652 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 9653 PetscErrorCode ierr; 9654 9655 PetscFunctionBegin; 9656 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 9657 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 9658 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9659 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 9660 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 9661 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 9662 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 9663 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 9664 switch (refiner) { 9665 case REFINER_NOOP: 9666 case REFINER_SIMPLEX_1D: 9667 case REFINER_SIMPLEX_2D: 9668 case REFINER_SIMPLEX_TO_HEX_2D: 9669 case REFINER_HEX_2D: 9670 case REFINER_SIMPLEX_3D: 9671 case REFINER_HEX_3D: 9672 case REFINER_SIMPLEX_TO_HEX_3D: 9673 break; 9674 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9675 case REFINER_HYBRID_SIMPLEX_3D: 9676 case REFINER_HYBRID_HEX_3D: 9677 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 9678 case REFINER_HYBRID_SIMPLEX_2D: 9679 case REFINER_HYBRID_HEX_2D: 9680 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 9681 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9682 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 9683 break; 9684 default: 9685 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9686 } 9687 cMax = cMax < 0 ? cEnd : cMax; 9688 fMax = fMax < 0 ? fEnd : fMax; 9689 eMax = eMax < 0 ? eEnd : eMax; 9690 for (l = 0; l < numLabels; ++l) { 9691 DMLabel label, labelNew; 9692 const char *lname; 9693 PetscBool isDepth, isCellType; 9694 IS valueIS; 9695 const PetscInt *values; 9696 PetscInt defVal; 9697 PetscInt numValues, val; 9698 9699 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 9700 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 9701 if (isDepth) continue; 9702 ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr); 9703 if (isCellType) continue; 9704 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 9705 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 9706 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 9707 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 9708 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 9709 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 9710 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 9711 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 9712 for (val = 0; val < numValues; ++val) { 9713 IS pointIS; 9714 const PetscInt *points; 9715 PetscInt numPoints, n; 9716 9717 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 9718 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 9719 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 9720 /* Ensure refined label is created with same number of strata as 9721 * original (even if no entries here). */ 9722 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 9723 for (n = 0; n < numPoints; ++n) { 9724 const PetscInt p = points[n]; 9725 switch (refiner) { 9726 case REFINER_SIMPLEX_1D: 9727 if ((p >= vStart) && (p < vEnd)) { 9728 /* Old vertices stay the same */ 9729 newp = vStartNew + (p - vStart); 9730 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9731 } else if ((p >= cStart) && (p < cEnd)) { 9732 /* Old cells add new cells and vertex */ 9733 newp = vStartNew + (vEnd - vStart) + (p - cStart); 9734 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9735 for (r = 0; r < 2; ++r) { 9736 newp = cStartNew + (p - cStart)*2 + r; 9737 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9738 } 9739 } 9740 break; 9741 case REFINER_SIMPLEX_2D: 9742 if ((p >= vStart) && (p < vEnd)) { 9743 /* Old vertices stay the same */ 9744 newp = vStartNew + (p - vStart); 9745 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9746 } else if ((p >= fStart) && (p < fEnd)) { 9747 /* Old faces add new faces and vertex */ 9748 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9749 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9750 for (r = 0; r < 2; ++r) { 9751 newp = fStartNew + (p - fStart)*2 + r; 9752 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9753 } 9754 } else if ((p >= cStart) && (p < cEnd)) { 9755 /* Old cells add new cells and interior faces */ 9756 for (r = 0; r < 4; ++r) { 9757 newp = cStartNew + (p - cStart)*4 + r; 9758 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9759 } 9760 for (r = 0; r < 3; ++r) { 9761 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9762 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9763 } 9764 } 9765 break; 9766 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9767 case REFINER_SIMPLEX_TO_HEX_2D: 9768 if ((p >= vStart) && (p < vEnd)) { 9769 /* Old vertices stay the same */ 9770 newp = vStartNew + (p - vStart); 9771 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9772 } else if ((p >= fStart) && (p < fEnd)) { 9773 /* Old faces add new faces and vertex */ 9774 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9775 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9776 for (r = 0; r < 2; ++r) { 9777 newp = fStartNew + (p - fStart)*2 + r; 9778 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9779 } 9780 } else if ((p >= cStart) && (p < cMax)) { 9781 /* Old cells add new cells, interior faces, and a vertex */ 9782 for (r = 0; r < 3; ++r) { 9783 newp = cStartNew + (p - cStart)*3 + r; 9784 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9785 } 9786 for (r = 0; r < 3; ++r) { 9787 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9788 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9789 } 9790 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9791 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9792 } else if ((p >= cMax) && (p < cEnd)) { 9793 /* Old hybrid cells add new cells, interior faces, and a vertex */ 9794 for (r = 0; r < 4; ++r) { 9795 newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9796 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9797 } 9798 for (r = 0; r < 4; ++r) { 9799 newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9800 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9801 } 9802 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9803 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9804 } 9805 break; 9806 case REFINER_HEX_2D: 9807 if ((p >= vStart) && (p < vEnd)) { 9808 /* Old vertices stay the same */ 9809 newp = vStartNew + (p - vStart); 9810 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9811 } else if ((p >= fStart) && (p < fEnd)) { 9812 /* Old faces add new faces and vertex */ 9813 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9814 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9815 for (r = 0; r < 2; ++r) { 9816 newp = fStartNew + (p - fStart)*2 + r; 9817 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9818 } 9819 } else if ((p >= cStart) && (p < cEnd)) { 9820 /* Old cells add new cells and interior faces and vertex */ 9821 for (r = 0; r < 4; ++r) { 9822 newp = cStartNew + (p - cStart)*4 + r; 9823 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9824 } 9825 for (r = 0; r < 4; ++r) { 9826 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9827 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9828 } 9829 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9830 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9831 } 9832 break; 9833 case REFINER_HYBRID_SIMPLEX_2D: 9834 if ((p >= vStart) && (p < vEnd)) { 9835 /* Old vertices stay the same */ 9836 newp = vStartNew + (p - vStart); 9837 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9838 } else if ((p >= fStart) && (p < fMax)) { 9839 /* Old interior faces add new faces and vertex */ 9840 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9841 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9842 for (r = 0; r < 2; ++r) { 9843 newp = fStartNew + (p - fStart)*2 + r; 9844 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9845 } 9846 } else if ((p >= fMax) && (p < fEnd)) { 9847 /* Old hybrid faces stay the same */ 9848 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9849 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9850 } else if ((p >= cStart) && (p < cMax)) { 9851 /* Old interior cells add new cells and interior faces */ 9852 for (r = 0; r < 4; ++r) { 9853 newp = cStartNew + (p - cStart)*4 + r; 9854 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9855 } 9856 for (r = 0; r < 3; ++r) { 9857 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9858 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9859 } 9860 } else if ((p >= cMax) && (p < cEnd)) { 9861 /* Old hybrid cells add new cells and hybrid face */ 9862 for (r = 0; r < 2; ++r) { 9863 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9864 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9865 } 9866 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9867 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9868 } 9869 break; 9870 case REFINER_HYBRID_HEX_2D: 9871 if ((p >= vStart) && (p < vEnd)) { 9872 /* Old vertices stay the same */ 9873 newp = vStartNew + (p - vStart); 9874 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9875 } else if ((p >= fStart) && (p < fMax)) { 9876 /* Old interior faces add new faces and vertex */ 9877 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9878 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9879 for (r = 0; r < 2; ++r) { 9880 newp = fStartNew + (p - fStart)*2 + r; 9881 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9882 } 9883 } else if ((p >= fMax) && (p < fEnd)) { 9884 /* Old hybrid faces stay the same */ 9885 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9886 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9887 } else if ((p >= cStart) && (p < cMax)) { 9888 /* Old interior cells add new cells, interior faces, and vertex */ 9889 for (r = 0; r < 4; ++r) { 9890 newp = cStartNew + (p - cStart)*4 + r; 9891 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9892 } 9893 for (r = 0; r < 4; ++r) { 9894 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9895 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9896 } 9897 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9898 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9899 } else if ((p >= cMax) && (p < cEnd)) { 9900 /* Old hybrid cells add new cells and hybrid face */ 9901 for (r = 0; r < 2; ++r) { 9902 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9903 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9904 } 9905 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9906 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9907 } 9908 break; 9909 case REFINER_SIMPLEX_3D: 9910 if ((p >= vStart) && (p < vEnd)) { 9911 /* Old vertices stay the same */ 9912 newp = vStartNew + (p - vStart); 9913 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9914 } else if ((p >= eStart) && (p < eEnd)) { 9915 /* Old edges add new edges and vertex */ 9916 for (r = 0; r < 2; ++r) { 9917 newp = eStartNew + (p - eStart)*2 + r; 9918 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9919 } 9920 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9921 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9922 } else if ((p >= fStart) && (p < fEnd)) { 9923 /* Old faces add new faces and edges */ 9924 for (r = 0; r < 4; ++r) { 9925 newp = fStartNew + (p - fStart)*4 + r; 9926 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9927 } 9928 for (r = 0; r < 3; ++r) { 9929 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 9930 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9931 } 9932 } else if ((p >= cStart) && (p < cEnd)) { 9933 /* Old cells add new cells and interior faces and edges */ 9934 for (r = 0; r < 8; ++r) { 9935 newp = cStartNew + (p - cStart)*8 + r; 9936 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9937 } 9938 for (r = 0; r < 8; ++r) { 9939 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 9940 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9941 } 9942 for (r = 0; r < 1; ++r) { 9943 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 9944 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9945 } 9946 } 9947 break; 9948 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9949 case REFINER_SIMPLEX_TO_HEX_3D: 9950 if ((p >= vStart) && (p < vEnd)) { 9951 /* Old vertices stay the same */ 9952 newp = vStartNew + (p - vStart); 9953 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9954 } else if ((p >= eStart) && (p < eMax)) { 9955 /* Interior edges add new edges and vertex */ 9956 for (r = 0; r < 2; ++r) { 9957 newp = eStartNew + (p - eStart)*2 + r; 9958 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9959 } 9960 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9961 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9962 } else if ((p >= eMax) && (p < eEnd)) { 9963 /* Hybrid edges stay the same */ 9964 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax; 9965 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9966 } else if ((p >= fStart) && (p < fMax)) { 9967 /* Old faces add new faces, edges and a vertex */ 9968 for (r = 0; r < 3; ++r) { 9969 newp = fStartNew + (p - fStart)*3 + r; 9970 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9971 } 9972 for (r = 0; r < 3; ++r) { 9973 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9974 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9975 } 9976 } else if ((p >= fMax) && (p < fEnd)) { 9977 /* Old hybrid faces add new faces and an edge */ 9978 for (r = 0; r < 2; ++r) { 9979 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9980 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9981 } 9982 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9983 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9984 } else if ((p >= cStart) && (p < cMax)) { 9985 /* Old cells add new cells and interior faces and edges and a vertex */ 9986 for (r = 0; r < 4; ++r) { 9987 newp = cStartNew + (p - cStart)*4 + r; 9988 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9989 } 9990 for (r = 0; r < 6; ++r) { 9991 newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9992 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9993 } 9994 for (r = 0; r < 4; ++r) { 9995 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9996 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9997 } 9998 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart; 9999 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10000 } else if ((p >= cMax) && (p < cEnd)) { 10001 /* Old hybrid cells add new cells and interior faces and an edge */ 10002 for (r = 0; r < 3; ++r) { 10003 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 10004 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10005 } 10006 for (r = 0; r < 3; ++r) { 10007 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 10008 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10009 } 10010 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax; 10011 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10012 } 10013 break; 10014 case REFINER_HYBRID_SIMPLEX_3D: 10015 if ((p >= vStart) && (p < vEnd)) { 10016 /* Interior vertices stay the same */ 10017 newp = vStartNew + (p - vStart); 10018 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10019 } else if ((p >= eStart) && (p < eMax)) { 10020 /* Interior edges add new edges and vertex */ 10021 for (r = 0; r < 2; ++r) { 10022 newp = eStartNew + (p - eStart)*2 + r; 10023 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10024 } 10025 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10026 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10027 } else if ((p >= eMax) && (p < eEnd)) { 10028 /* Hybrid edges stay the same */ 10029 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 10030 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10031 } else if ((p >= fStart) && (p < fMax)) { 10032 /* Interior faces add new faces and edges */ 10033 for (r = 0; r < 4; ++r) { 10034 newp = fStartNew + (p - fStart)*4 + r; 10035 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10036 } 10037 for (r = 0; r < 3; ++r) { 10038 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 10039 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10040 } 10041 } else if ((p >= fMax) && (p < fEnd)) { 10042 /* Hybrid faces add new faces and edges */ 10043 for (r = 0; r < 2; ++r) { 10044 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 10045 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10046 } 10047 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 10048 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10049 } else if ((p >= cStart) && (p < cMax)) { 10050 /* Interior cells add new cells, faces, and edges */ 10051 for (r = 0; r < 8; ++r) { 10052 newp = cStartNew + (p - cStart)*8 + r; 10053 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10054 } 10055 for (r = 0; r < 8; ++r) { 10056 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 10057 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10058 } 10059 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 10060 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10061 } else if ((p >= cMax) && (p < cEnd)) { 10062 /* Hybrid cells add new cells and faces */ 10063 for (r = 0; r < 4; ++r) { 10064 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10065 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10066 } 10067 for (r = 0; r < 3; ++r) { 10068 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 10069 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10070 } 10071 } 10072 break; 10073 case REFINER_HEX_3D: 10074 if ((p >= vStart) && (p < vEnd)) { 10075 /* Old vertices stay the same */ 10076 newp = vStartNew + (p - vStart); 10077 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10078 } else if ((p >= eStart) && (p < eEnd)) { 10079 /* Old edges add new edges and vertex */ 10080 for (r = 0; r < 2; ++r) { 10081 newp = eStartNew + (p - eStart)*2 + r; 10082 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10083 } 10084 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10085 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10086 } else if ((p >= fStart) && (p < fEnd)) { 10087 /* Old faces add new faces, edges, and vertex */ 10088 for (r = 0; r < 4; ++r) { 10089 newp = fStartNew + (p - fStart)*4 + r; 10090 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10091 } 10092 for (r = 0; r < 4; ++r) { 10093 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 10094 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10095 } 10096 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 10097 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10098 } else if ((p >= cStart) && (p < cEnd)) { 10099 /* Old cells add new cells, faces, edges, and vertex */ 10100 for (r = 0; r < 8; ++r) { 10101 newp = cStartNew + (p - cStart)*8 + r; 10102 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10103 } 10104 for (r = 0; r < 12; ++r) { 10105 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 10106 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10107 } 10108 for (r = 0; r < 6; ++r) { 10109 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 10110 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10111 } 10112 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 10113 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10114 } 10115 break; 10116 case REFINER_HYBRID_HEX_3D: 10117 if ((p >= vStart) && (p < vEnd)) { 10118 /* Interior vertices stay the same */ 10119 newp = vStartNew + (p - vStart); 10120 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10121 } else if ((p >= eStart) && (p < eMax)) { 10122 /* Interior edges add new edges and vertex */ 10123 for (r = 0; r < 2; ++r) { 10124 newp = eStartNew + (p - eStart)*2 + r; 10125 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10126 } 10127 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10128 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10129 } else if ((p >= eMax) && (p < eEnd)) { 10130 /* Hybrid edges stay the same */ 10131 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 10132 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10133 } else if ((p >= fStart) && (p < fMax)) { 10134 /* Interior faces add new faces, edges, and vertex */ 10135 for (r = 0; r < 4; ++r) { 10136 newp = fStartNew + (p - fStart)*4 + r; 10137 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10138 } 10139 for (r = 0; r < 4; ++r) { 10140 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 10141 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10142 } 10143 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 10144 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10145 } else if ((p >= fMax) && (p < fEnd)) { 10146 /* Hybrid faces add new faces and edges */ 10147 for (r = 0; r < 2; ++r) { 10148 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 10149 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10150 } 10151 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 10152 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10153 } else if ((p >= cStart) && (p < cMax)) { 10154 /* Interior cells add new cells, faces, edges, and vertex */ 10155 for (r = 0; r < 8; ++r) { 10156 newp = cStartNew + (p - cStart)*8 + r; 10157 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10158 } 10159 for (r = 0; r < 12; ++r) { 10160 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 10161 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10162 } 10163 for (r = 0; r < 6; ++r) { 10164 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 10165 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10166 } 10167 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 10168 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10169 } else if ((p >= cMax) && (p < cEnd)) { 10170 /* Hybrid cells add new cells, faces, and edges */ 10171 for (r = 0; r < 4; ++r) { 10172 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10173 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10174 } 10175 for (r = 0; r < 4; ++r) { 10176 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 10177 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10178 } 10179 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 10180 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10181 } 10182 break; 10183 default: 10184 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 10185 } 10186 } 10187 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 10188 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 10189 } 10190 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 10191 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 10192 } 10193 PetscFunctionReturn(0); 10194 } 10195 10196 /* This will only work for interpolated meshes */ 10197 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 10198 { 10199 DM rdm; 10200 PetscInt *depthSize; 10201 PetscInt dim, embedDim, depth = 0, d, pStart = 0, pEnd = 0; 10202 PetscErrorCode ierr; 10203 10204 PetscFunctionBegin; 10205 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 10206 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 10207 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10208 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 10209 ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr); 10210 ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr); 10211 /* Calculate number of new points of each depth */ 10212 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10213 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 10214 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10215 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 10216 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10217 /* Step 1: Set chart */ 10218 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 10219 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 10220 /* Step 2: Set cone/support sizes (automatically stratifies) */ 10221 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10222 /* Step 3: Setup refined DM */ 10223 ierr = DMSetUp(rdm);CHKERRQ(ierr); 10224 /* Step 4: Set cones and supports (automatically symmetrizes) */ 10225 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10226 /* Step 5: Create pointSF */ 10227 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10228 /* Step 6: Create labels */ 10229 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10230 /* Step 7: Set coordinates */ 10231 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10232 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10233 10234 *dmRefined = rdm; 10235 PetscFunctionReturn(0); 10236 } 10237 10238 /*@ 10239 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 10240 10241 Input Parameter: 10242 . dm - The coarse DM 10243 10244 Output Parameter: 10245 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 10246 10247 Level: developer 10248 10249 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 10250 @*/ 10251 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 10252 { 10253 CellRefiner cellRefiner; 10254 PetscInt *depthSize, *fpoints; 10255 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 10256 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 10257 PetscErrorCode ierr; 10258 10259 PetscFunctionBegin; 10260 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10261 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 10262 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 10263 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10264 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10265 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10266 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 10267 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 10268 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 10269 switch (cellRefiner) { 10270 case REFINER_SIMPLEX_1D: 10271 case REFINER_SIMPLEX_2D: 10272 case REFINER_HYBRID_SIMPLEX_2D: 10273 case REFINER_HEX_2D: 10274 case REFINER_HYBRID_HEX_2D: 10275 case REFINER_SIMPLEX_3D: 10276 case REFINER_HYBRID_SIMPLEX_3D: 10277 case REFINER_HEX_3D: 10278 case REFINER_HYBRID_HEX_3D: 10279 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 10280 break; 10281 default: 10282 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[cellRefiner]); 10283 } 10284 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 10285 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10286 PetscFunctionReturn(0); 10287 } 10288 10289 /*@ 10290 DMPlexSetRefinementUniform - Set the flag for uniform refinement 10291 10292 Input Parameters: 10293 + dm - The DM 10294 - refinementUniform - The flag for uniform refinement 10295 10296 Level: developer 10297 10298 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10299 @*/ 10300 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 10301 { 10302 DM_Plex *mesh = (DM_Plex*) dm->data; 10303 10304 PetscFunctionBegin; 10305 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10306 mesh->refinementUniform = refinementUniform; 10307 PetscFunctionReturn(0); 10308 } 10309 10310 /*@ 10311 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 10312 10313 Input Parameter: 10314 . dm - The DM 10315 10316 Output Parameter: 10317 . refinementUniform - The flag for uniform refinement 10318 10319 Level: developer 10320 10321 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10322 @*/ 10323 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 10324 { 10325 DM_Plex *mesh = (DM_Plex*) dm->data; 10326 10327 PetscFunctionBegin; 10328 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10329 PetscValidPointer(refinementUniform, 2); 10330 *refinementUniform = mesh->refinementUniform; 10331 PetscFunctionReturn(0); 10332 } 10333 10334 /*@ 10335 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 10336 10337 Input Parameters: 10338 + dm - The DM 10339 - refinementLimit - The maximum cell volume in the refined mesh 10340 10341 Level: developer 10342 10343 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10344 @*/ 10345 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 10346 { 10347 DM_Plex *mesh = (DM_Plex*) dm->data; 10348 10349 PetscFunctionBegin; 10350 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10351 mesh->refinementLimit = refinementLimit; 10352 PetscFunctionReturn(0); 10353 } 10354 10355 /*@ 10356 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 10357 10358 Input Parameter: 10359 . dm - The DM 10360 10361 Output Parameter: 10362 . refinementLimit - The maximum cell volume in the refined mesh 10363 10364 Level: developer 10365 10366 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10367 @*/ 10368 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 10369 { 10370 DM_Plex *mesh = (DM_Plex*) dm->data; 10371 10372 PetscFunctionBegin; 10373 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10374 PetscValidPointer(refinementLimit, 2); 10375 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 10376 *refinementLimit = mesh->refinementLimit; 10377 PetscFunctionReturn(0); 10378 } 10379 10380 /*@ 10381 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 10382 10383 Input Parameters: 10384 + dm - The DM 10385 - refinementFunc - Function giving the maximum cell volume in the refined mesh 10386 10387 Note: The calling sequence is refinementFunc(coords, limit) 10388 $ coords - Coordinates of the current point, usually a cell centroid 10389 $ limit - The maximum cell volume for a cell containing this point 10390 10391 Level: developer 10392 10393 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10394 @*/ 10395 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 10396 { 10397 DM_Plex *mesh = (DM_Plex*) dm->data; 10398 10399 PetscFunctionBegin; 10400 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10401 mesh->refinementFunc = refinementFunc; 10402 PetscFunctionReturn(0); 10403 } 10404 10405 /*@ 10406 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 10407 10408 Input Parameter: 10409 . dm - The DM 10410 10411 Output Parameter: 10412 . refinementFunc - Function giving the maximum cell volume in the refined mesh 10413 10414 Note: The calling sequence is refinementFunc(coords, limit) 10415 $ coords - Coordinates of the current point, usually a cell centroid 10416 $ limit - The maximum cell volume for a cell containing this point 10417 10418 Level: developer 10419 10420 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10421 @*/ 10422 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 10423 { 10424 DM_Plex *mesh = (DM_Plex*) dm->data; 10425 10426 PetscFunctionBegin; 10427 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10428 PetscValidPointer(refinementFunc, 2); 10429 *refinementFunc = mesh->refinementFunc; 10430 PetscFunctionReturn(0); 10431 } 10432 10433 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 10434 { 10435 DMPolytopeType ct; 10436 PetscInt dim, cStart, cEnd, cMax, fMax; 10437 PetscErrorCode ierr; 10438 10439 PetscFunctionBegin; 10440 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10441 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 10442 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 10443 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 10444 /* TODO Must tag hybrid cells with correct cell types */ 10445 ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 10446 switch (ct) { 10447 case DM_POLYTOPE_SEGMENT: *cellRefiner = REFINER_SIMPLEX_1D; break; 10448 case DM_POLYTOPE_TRIANGLE: if (cMax >= 0) {*cellRefiner = REFINER_HYBRID_SIMPLEX_2D; break;} 10449 else {*cellRefiner = REFINER_SIMPLEX_2D; break;} 10450 case DM_POLYTOPE_QUADRILATERAL: if (cMax >= 0) {*cellRefiner = REFINER_HYBRID_HEX_2D; break;} /* Why did this have fMax >= 0 ??? */ 10451 else {*cellRefiner = REFINER_HEX_2D; break;} 10452 case DM_POLYTOPE_TETRAHEDRON: if (cMax >= 0) {*cellRefiner = REFINER_HYBRID_SIMPLEX_3D; break;} 10453 else {*cellRefiner = REFINER_SIMPLEX_3D; break;} 10454 case DM_POLYTOPE_HEXAHEDRON: if (cMax >= 0) {*cellRefiner = REFINER_HYBRID_HEX_3D; break;} 10455 else {*cellRefiner = REFINER_HEX_3D; break;} 10456 case DM_POLYTOPE_SEG_PRISM_TENSOR: *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; break; 10457 case DM_POLYTOPE_TRI_PRISM_TENSOR: *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; break; 10458 case DM_POLYTOPE_QUAD_PRISM_TENSOR: *cellRefiner = REFINER_HYBRID_HEX_3D; break; 10459 default: SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No cell refiner for cell %D with type %s", cStart, DMPolytopeTypes[ct]); 10460 } 10461 PetscFunctionReturn(0); 10462 } 10463 10464 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 10465 { 10466 PetscBool isUniform; 10467 PetscErrorCode ierr; 10468 10469 PetscFunctionBegin; 10470 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10471 if (isUniform) { 10472 CellRefiner cellRefiner; 10473 PetscBool localized; 10474 10475 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10476 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10477 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 10478 ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 10479 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 10480 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 10481 } else { 10482 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 10483 } 10484 PetscFunctionReturn(0); 10485 } 10486 10487 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 10488 { 10489 DM cdm = dm; 10490 PetscInt r; 10491 PetscBool isUniform, localized; 10492 PetscErrorCode ierr; 10493 10494 PetscFunctionBegin; 10495 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10496 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10497 if (isUniform) { 10498 for (r = 0; r < nlevels; ++r) { 10499 CellRefiner cellRefiner; 10500 10501 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 10502 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 10503 ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 10504 ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 10505 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10506 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10507 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10508 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 10509 cdm = dmRefined[r]; 10510 } 10511 } else { 10512 for (r = 0; r < nlevels; ++r) { 10513 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 10514 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10515 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10516 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10517 cdm = dmRefined[r]; 10518 } 10519 } 10520 PetscFunctionReturn(0); 10521 } 10522