1 #include <petsc/private/dmpleximpl.h> /*I "petscdmplex.h" I*/ 2 #include <petscsf.h> 3 4 const char * const CellRefiners[] = {"NOOP", "SIMPLEX_1D", "SIMPLEX_2D", "HYBRID_SIMPLEX_2D", "SIMPLEX_TO_HEX_2D", "HYBRID_SIMPLEX_TO_HEX_2D", "HEX_2D", "HYBRID_HEX_2D", 5 "SIMPLEX_3D", "HYBRID_SIMPLEX_3D", "SIMPLEX_TO_HEX_3D", "HYBRID_SIMPLEX_TO_HEX_3D", "HEX_3D", "HYBRID_HEX_3D", "CellRefiners", "REFINER_", 0}; 6 7 PETSC_STATIC_INLINE PetscErrorCode GetDepthStart_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cStart, PetscInt *fStart, PetscInt *eStart, PetscInt *vStart) 8 { 9 PetscFunctionBegin; 10 if (cStart) *cStart = 0; 11 if (vStart) *vStart = depth < 0 ? 0 : depthSize[depth]; 12 if (fStart) *fStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 13 if (eStart) *eStart = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 14 PetscFunctionReturn(0); 15 } 16 17 PETSC_STATIC_INLINE PetscErrorCode GetDepthEnd_Private(PetscInt depth, PetscInt depthSize[], PetscInt *cEnd, PetscInt *fEnd, PetscInt *eEnd, PetscInt *vEnd) 18 { 19 PetscFunctionBegin; 20 if (cEnd) *cEnd = depth < 0 ? 0 : depthSize[depth]; 21 if (vEnd) *vEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0]; 22 if (fEnd) *fEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1]; 23 if (eEnd) *eEnd = depth < 0 ? 0 : depthSize[depth] + depthSize[0] + depthSize[depth-1] + depthSize[1]; 24 PetscFunctionReturn(0); 25 } 26 27 /* 28 Note that j and invj are non-square: 29 v0 + j x_face = x_cell 30 invj (x_cell - v0) = x_face 31 */ 32 PetscErrorCode CellRefinerGetAffineFaceTransforms_Internal(CellRefiner refiner, PetscInt *numFaces, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[], PetscReal *detj[]) 33 { 34 PetscReal *v = NULL, *j = NULL, *invj = NULL, *dj = NULL; 35 PetscInt cdim, fdim; 36 PetscErrorCode ierr; 37 38 PetscFunctionBegin; 39 switch (refiner) { 40 case REFINER_NOOP: break; 41 case REFINER_SIMPLEX_2D: 42 /* 43 2 44 |\ 45 | \ 46 | \ 47 | \ 48 | \ 49 | \ 50 | \ 51 2 1 52 | \ 53 | \ 54 | \ 55 0---0-------1 56 */ 57 cdim = 2; 58 fdim = 1; 59 if (numFaces) *numFaces = 3; 60 if (v0) { 61 ierr = PetscMalloc1(3*cdim, &v);CHKERRQ(ierr); 62 ierr = PetscMalloc1(3*cdim*fdim, &j);CHKERRQ(ierr); 63 ierr = PetscMalloc1(3*cdim*fdim, &invj);CHKERRQ(ierr); 64 ierr = PetscMalloc1(3, &dj);CHKERRQ(ierr); 65 /* 0 */ 66 v[0+0] = 0.0; v[0+1] = -1.0; 67 j[0+0] = 1.0; 68 j[0+1] = 0.0; 69 invj[0+0] = 1.0; invj[0+1] = 0.0; 70 dj[0] = 1.0; 71 /* 1 */ 72 v[2+0] = 0.0; v[2+1] = 0.0; 73 j[2+0] = -1.0; 74 j[2+1] = 1.0; 75 invj[2+0] = -0.5; invj[2+1] = 0.5; 76 dj[1] = 1.414213562373095; 77 /* 2 */ 78 v[4+0] = -1.0; v[4+1] = 0.0; 79 j[4+0] = 0.0; 80 j[4+1] = -1.0; 81 invj[4+0] = 0.0; invj[4+1] = -1.0; 82 dj[2] = 1.0; 83 } 84 break; 85 case REFINER_HEX_2D: 86 /* 87 3---------2---------2 88 | | 89 | | 90 | | 91 3 1 92 | | 93 | | 94 | | 95 0---------0---------1 96 */ 97 cdim = 2; 98 fdim = 1; 99 if (numFaces) *numFaces = 4; 100 if (v0) { 101 ierr = PetscMalloc1(4*cdim, &v);CHKERRQ(ierr); 102 ierr = PetscMalloc1(4*cdim*fdim, &j);CHKERRQ(ierr); 103 ierr = PetscMalloc1(4*cdim*fdim, &invj);CHKERRQ(ierr); 104 ierr = PetscMalloc1(4, &dj);CHKERRQ(ierr); 105 /* 0 */ 106 v[0+0] = 0.0; v[0+1] = -1.0; 107 j[0+0] = 1.0; 108 j[0+1] = 0.0; 109 invj[0+0] = 1.0; invj[0+1] = 0.0; 110 dj[0] = 1.0; 111 /* 1 */ 112 v[2+0] = 1.0; v[2+1] = 0.0; 113 j[2+0] = 0.0; 114 j[2+1] = 1.0; 115 invj[2+0] = 0.0; invj[2+1] = 1.0; 116 dj[1] = 1.0; 117 /* 2 */ 118 v[4+0] = 0.0; v[4+1] = 1.0; 119 j[4+0] = -1.0; 120 j[4+1] = 0.0; 121 invj[4+0] = -1.0; invj[4+1] = 0.0; 122 dj[2] = 1.0; 123 /* 3 */ 124 v[6+0] = -1.0; v[6+1] = 0.0; 125 j[6+0] = 0.0; 126 j[6+1] = -1.0; 127 invj[6+0] = 0.0; invj[6+1] = -1.0; 128 dj[3] = 1.0; 129 } 130 break; 131 default: 132 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 133 } 134 if (v0) {*v0 = v;} 135 else {ierr = PetscFree(v);CHKERRQ(ierr);} 136 if (jac) {*jac = j;} 137 else {ierr = PetscFree(j);CHKERRQ(ierr);} 138 if (invjac) {*invjac = invj;} 139 else {ierr = PetscFree(invj);CHKERRQ(ierr);} 140 if (invjac) {*invjac = invj;} 141 else {ierr = PetscFree(invj);CHKERRQ(ierr);} 142 if (detj) {*detj = dj;} 143 else {ierr = PetscFree(dj);CHKERRQ(ierr);} 144 PetscFunctionReturn(0); 145 } 146 147 /* Gets the affine map from the original cell to each subcell */ 148 PetscErrorCode CellRefinerGetAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 149 { 150 PetscReal *v = NULL, *j = NULL, *invj = NULL, detJ; 151 PetscInt dim, s; 152 PetscErrorCode ierr; 153 154 PetscFunctionBegin; 155 switch (refiner) { 156 case REFINER_NOOP: break; 157 case REFINER_SIMPLEX_2D: 158 /* 159 2 160 |\ 161 | \ 162 | \ 163 | \ 164 | C \ 165 | \ 166 | \ 167 2---1---1 168 |\ D / \ 169 | 2 0 \ 170 |A \ / B \ 171 0---0-------1 172 */ 173 dim = 2; 174 if (numSubcells) *numSubcells = 4; 175 if (v0) { 176 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 177 /* A */ 178 v[0+0] = -1.0; v[0+1] = -1.0; 179 j[0+0] = 0.5; j[0+1] = 0.0; 180 j[0+2] = 0.0; j[0+3] = 0.5; 181 /* B */ 182 v[2+0] = 0.0; v[2+1] = -1.0; 183 j[4+0] = 0.5; j[4+1] = 0.0; 184 j[4+2] = 0.0; j[4+3] = 0.5; 185 /* C */ 186 v[4+0] = -1.0; v[4+1] = 0.0; 187 j[8+0] = 0.5; j[8+1] = 0.0; 188 j[8+2] = 0.0; j[8+3] = 0.5; 189 /* D */ 190 v[6+0] = 0.0; v[6+1] = -1.0; 191 j[12+0] = 0.0; j[12+1] = -0.5; 192 j[12+2] = 0.5; j[12+3] = 0.5; 193 for (s = 0; s < 4; ++s) { 194 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 195 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 196 } 197 } 198 break; 199 case REFINER_HEX_2D: 200 /* 201 3---------2---------2 202 | | | 203 | D 2 C | 204 | | | 205 3----3----0----1----1 206 | | | 207 | A 0 B | 208 | | | 209 0---------0---------1 210 */ 211 dim = 2; 212 if (numSubcells) *numSubcells = 4; 213 if (v0) { 214 ierr = PetscMalloc3(4*dim,&v,4*dim*dim,&j,4*dim*dim,&invj);CHKERRQ(ierr); 215 /* A */ 216 v[0+0] = -1.0; v[0+1] = -1.0; 217 j[0+0] = 0.5; j[0+1] = 0.0; 218 j[0+2] = 0.0; j[0+3] = 0.5; 219 /* B */ 220 v[2+0] = 0.0; v[2+1] = -1.0; 221 j[4+0] = 0.5; j[4+1] = 0.0; 222 j[4+2] = 0.0; j[4+3] = 0.5; 223 /* C */ 224 v[4+0] = 0.0; v[4+1] = 0.0; 225 j[8+0] = 0.5; j[8+1] = 0.0; 226 j[8+2] = 0.0; j[8+3] = 0.5; 227 /* D */ 228 v[6+0] = -1.0; v[6+1] = 0.0; 229 j[12+0] = 0.5; j[12+1] = 0.0; 230 j[12+2] = 0.0; j[12+3] = 0.5; 231 for (s = 0; s < 4; ++s) { 232 DMPlex_Det2D_Internal(&detJ, &j[s*dim*dim]); 233 DMPlex_Invert2D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 234 } 235 } 236 break; 237 case REFINER_HEX_3D: 238 /* 239 Bottom (viewed from top) Top 240 1---------2---------2 7---------2---------6 241 | | | | | | 242 | B 2 C | | H 2 G | 243 | | | | | | 244 3----3----0----1----1 3----3----0----1----1 245 | | | | | | 246 | A 0 D | | E 0 F | 247 | | | | | | 248 0---------0---------3 4---------0---------5 249 */ 250 dim = 3; 251 if (numSubcells) *numSubcells = 8; 252 if (v0) { 253 ierr = PetscMalloc3(8*dim,&v,8*dim*dim,&j,8*dim*dim,&invj);CHKERRQ(ierr); 254 /* A */ 255 v[0+0] = -1.0; v[0+1] = -1.0; v[0+2] = -1.0; 256 j[0+0] = 0.5; j[0+1] = 0.0; j[0+2] = 0.0; 257 j[0+3] = 0.0; j[0+4] = 0.5; j[0+5] = 0.0; 258 j[0+6] = 0.0; j[0+7] = 0.0; j[0+8] = 0.5; 259 /* B */ 260 v[3+0] = -1.0; v[3+1] = 0.0; v[3+2] = -1.0; 261 j[9+0] = 0.5; j[9+1] = 0.0; j[9+2] = 0.0; 262 j[9+3] = 0.0; j[9+4] = 0.5; j[9+5] = 0.0; 263 j[9+6] = 0.0; j[9+7] = 0.0; j[9+8] = 0.5; 264 /* C */ 265 v[6+0] = 0.0; v[6+1] = 0.0; v[6+2] = -1.0; 266 j[18+0] = 0.5; j[18+1] = 0.0; j[18+2] = 0.0; 267 j[18+3] = 0.0; j[18+4] = 0.5; j[18+5] = 0.0; 268 j[18+6] = 0.0; j[18+7] = 0.0; j[18+8] = 0.5; 269 /* D */ 270 v[9+0] = 0.0; v[9+1] = -1.0; v[9+2] = -1.0; 271 j[27+0] = 0.5; j[27+1] = 0.0; j[27+2] = 0.0; 272 j[27+3] = 0.0; j[27+4] = 0.5; j[27+5] = 0.0; 273 j[27+6] = 0.0; j[27+7] = 0.0; j[27+8] = 0.5; 274 /* E */ 275 v[12+0] = -1.0; v[12+1] = -1.0; v[12+2] = 0.0; 276 j[36+0] = 0.5; j[36+1] = 0.0; j[36+2] = 0.0; 277 j[36+3] = 0.0; j[36+4] = 0.5; j[36+5] = 0.0; 278 j[36+6] = 0.0; j[36+7] = 0.0; j[36+8] = 0.5; 279 /* F */ 280 v[15+0] = 0.0; v[15+1] = -1.0; v[15+2] = 0.0; 281 j[45+0] = 0.5; j[45+1] = 0.0; j[45+2] = 0.0; 282 j[45+3] = 0.0; j[45+4] = 0.5; j[45+5] = 0.0; 283 j[45+6] = 0.0; j[45+7] = 0.0; j[45+8] = 0.5; 284 /* G */ 285 v[18+0] = 0.0; v[18+1] = 0.0; v[18+2] = 0.0; 286 j[54+0] = 0.5; j[54+1] = 0.0; j[54+2] = 0.0; 287 j[54+3] = 0.0; j[54+4] = 0.5; j[54+5] = 0.0; 288 j[54+6] = 0.0; j[54+7] = 0.0; j[54+8] = 0.5; 289 /* H */ 290 v[21+0] = -1.0; v[21+1] = 0.0; v[21+2] = 0.0; 291 j[63+0] = 0.5; j[63+1] = 0.0; j[63+2] = 0.0; 292 j[63+3] = 0.0; j[63+4] = 0.5; j[63+5] = 0.0; 293 j[63+6] = 0.0; j[63+7] = 0.0; j[63+8] = 0.5; 294 for (s = 0; s < 8; ++s) { 295 DMPlex_Det3D_Internal(&detJ, &j[s*dim*dim]); 296 DMPlex_Invert3D_Internal(&invj[s*dim*dim], &j[s*dim*dim], detJ); 297 } 298 } 299 break; 300 default: 301 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 302 } 303 if (v0) {*v0 = v; *jac = j; *invjac = invj;} 304 PetscFunctionReturn(0); 305 } 306 307 PetscErrorCode CellRefinerRestoreAffineTransforms_Internal(CellRefiner refiner, PetscInt *numSubcells, PetscReal *v0[], PetscReal *jac[], PetscReal *invjac[]) 308 { 309 PetscErrorCode ierr; 310 311 PetscFunctionBegin; 312 ierr = PetscFree3(*v0,*jac,*invjac);CHKERRQ(ierr); 313 PetscFunctionReturn(0); 314 } 315 316 /* Should this be here or in the DualSpace somehow? */ 317 PetscErrorCode CellRefinerInCellTest_Internal(CellRefiner refiner, const PetscReal point[], PetscBool *inside) 318 { 319 PetscReal sum = 0.0; 320 PetscInt d; 321 322 PetscFunctionBegin; 323 *inside = PETSC_TRUE; 324 switch (refiner) { 325 case REFINER_NOOP: break; 326 case REFINER_SIMPLEX_2D: 327 for (d = 0; d < 2; ++d) { 328 if (point[d] < -1.0) {*inside = PETSC_FALSE; break;} 329 sum += point[d]; 330 } 331 if (sum > 1.0e-10) {*inside = PETSC_FALSE; break;} 332 break; 333 case REFINER_HEX_2D: 334 for (d = 0; d < 2; ++d) if ((point[d] < -1.00000000001) || (point[d] > 1.000000000001)) {*inside = PETSC_FALSE; break;} 335 break; 336 case REFINER_HEX_3D: 337 for (d = 0; d < 3; d++) if (PetscAbsReal(point[d]) > 1 + PETSC_SMALL) {*inside = PETSC_FALSE; break;} 338 break; 339 default: 340 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 341 } 342 PetscFunctionReturn(0); 343 } 344 345 static PetscErrorCode CellRefinerGetSizes(CellRefiner refiner, DM dm, PetscInt depthSize[]) 346 { 347 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 348 PetscErrorCode ierr; 349 350 PetscFunctionBegin; 351 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 352 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 353 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 354 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 355 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 356 switch (refiner) { 357 case REFINER_NOOP: 358 break; 359 case REFINER_SIMPLEX_1D: 360 depthSize[0] = vEnd - vStart + cEnd - cStart; /* Add a vertex on every cell. */ 361 depthSize[1] = 2*(cEnd - cStart); /* Split every cell in 2. */ 362 break; 363 case REFINER_SIMPLEX_2D: 364 depthSize[0] = vEnd - vStart + fEnd - fStart; /* Add a vertex on every face */ 365 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 366 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 367 break; 368 case REFINER_HYBRID_SIMPLEX_2D: 369 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 370 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 371 depthSize[0] = vEnd - vStart + fMax - fStart; /* Add a vertex on every face, but not hybrid faces */ 372 depthSize[1] = 2*(fMax - fStart) + 3*(cMax - cStart) + (fEnd - fMax) + (cEnd - cMax); /* Every interior face is split into 2 faces, 3 faces are added for each interior cell, and one in each hybrid cell */ 373 depthSize[2] = 4*(cMax - cStart) + 2*(cEnd - cMax); /* Interior cells split into 4 cells, hybrid cells split into 2 cells */ 374 break; 375 case REFINER_SIMPLEX_TO_HEX_2D: 376 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 377 depthSize[1] = 2*(fEnd - fStart) + 3*(cEnd - cStart); /* Every face is split into 2 faces and 3 faces are added for each cell */ 378 depthSize[2] = 3*(cEnd - cStart); /* Every cell split into 3 cells */ 379 break; 380 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 381 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 382 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 383 depthSize[1] = 2*(fEnd - fStart) + 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every face is split into 2 faces and 3 faces are added for each cell. 4 for each hybrid cell */ 384 depthSize[2] = 3*(cMax - cStart) + 4*(cEnd - cMax); /* Every cell split into 3 cells, hybrid cells split in 4 */ 385 break; 386 case REFINER_HEX_2D: 387 depthSize[0] = vEnd - vStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every face and cell */ 388 depthSize[1] = 2*(fEnd - fStart) + 4*(cEnd - cStart); /* Every face is split into 2 faces and 4 faces are added for each cell */ 389 depthSize[2] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 390 break; 391 case REFINER_HYBRID_HEX_2D: 392 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 393 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 394 /* Quadrilateral */ 395 depthSize[0] = vEnd - vStart + fMax - fStart + cMax - cStart; /* Add a vertex on every face and cell */ 396 depthSize[1] = 2*(fMax - fStart) + 4*(cMax - cStart); /* Every face is split into 2 faces, and 4 faces are added for each cell */ 397 depthSize[2] = 4*(cMax - cStart); /* Every cell split into 4 cells */ 398 /* Segment Prisms */ 399 depthSize[0] += 0; /* No hybrid vertices */ 400 depthSize[1] += (fEnd - fMax) + (cEnd - cMax); /* Every hybrid face remains and 1 faces is added for each hybrid cell */ 401 depthSize[2] += 2*(cEnd - cMax); /* Every hybrid cell split into 2 cells */ 402 break; 403 case REFINER_SIMPLEX_3D: 404 depthSize[0] = vEnd - vStart + eEnd - eStart; /* Add a vertex on every edge */ 405 depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + (cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 1 edge for each cell */ 406 depthSize[2] = 4*(fEnd - fStart) + 8*(cEnd - cStart); /* Every face split into 4 faces and 8 faces are added for each cell */ 407 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 408 break; 409 case REFINER_HYBRID_SIMPLEX_3D: 410 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 411 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 412 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 413 /* Tetrahedra */ 414 depthSize[0] = vEnd - vStart + eMax - eStart; /* Add a vertex on every interior edge */ 415 depthSize[1] = 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 1 edge for each interior cell */ 416 depthSize[2] = 4*(fMax - fStart) + 8*(cMax - cStart); /* Every interior face split into 4 faces, 8 faces added for each interior cell */ 417 depthSize[3] = 8*(cMax - cStart); /* Every interior cell split into 8 cells */ 418 /* Triangular Prisms */ 419 depthSize[0] += 0; /* No hybrid vertices */ 420 depthSize[1] += (eEnd - eMax) + (fEnd - fMax); /* Every hybrid edge remains, 1 edge for every hybrid face */ 421 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 422 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 423 break; 424 case REFINER_SIMPLEX_TO_HEX_3D: 425 depthSize[0] = vEnd - vStart + fEnd - fStart + eEnd - eStart + cEnd - cStart; /* Add a vertex on every face, edge and cell */ 426 depthSize[1] = 2*(eEnd - eStart) + 3*(fEnd - fStart) + 4*(cEnd - cStart); /* Every edge is split into 2 edges, 3 edges are added for each face, and 4 for each cell */ 427 depthSize[2] = 3*(fEnd - fStart) + 6*(cEnd - cStart); /* Every face is split into 3 faces and 6 faces are added for each cell */ 428 depthSize[3] = 4*(cEnd - cStart); /* Every cell split into 4 cells */ 429 break; 430 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 431 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 432 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 433 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 434 /* Tetrahedra */ 435 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every interior edge, face and cell */ 436 depthSize[1] = 2*(eMax - eStart) + 3*(fMax - fStart) + 4*(cMax - cStart); /* Every interior edge split into 2 edges, 3 edges added for each interior face, 4 edges for each interior cell */ 437 depthSize[2] = 3*(fMax - fStart) + 6*(cMax - cStart); /* Every interior face split into 3 faces, 6 faces added for each interior cell */ 438 depthSize[3] = 4*(cMax - cStart); /* Every interior cell split into 8 cells */ 439 /* Triangular Prisms */ 440 depthSize[0] += 0; /* No hybrid vertices */ 441 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and cell */ 442 depthSize[2] += 2*(fEnd - fMax) + 3*(cEnd - cMax); /* Every hybrid face split into 2 faces and 3 faces are added for each hybrid cell */ 443 depthSize[3] += 3*(cEnd - cMax); /* Every hybrid cell split into 3 cells */ 444 break; 445 case REFINER_HEX_3D: 446 depthSize[0] = vEnd - vStart + eEnd - eStart + fEnd - fStart + cEnd - cStart; /* Add a vertex on every edge, face and cell */ 447 depthSize[1] = 2*(eEnd - eStart) + 4*(fEnd - fStart) + 6*(cEnd - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */ 448 depthSize[2] = 4*(fEnd - fStart) + 12*(cEnd - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 449 depthSize[3] = 8*(cEnd - cStart); /* Every cell split into 8 cells */ 450 break; 451 case REFINER_HYBRID_HEX_3D: 452 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 453 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 454 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 455 /* Hexahedra */ 456 depthSize[0] = vEnd - vStart + eMax - eStart + fMax - fStart + cMax - cStart; /* Add a vertex on every edge, face and cell */ 457 depthSize[1] = 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart); /* Every edge is split into 2 edge, 4 edges are added for each face, and 6 edges for each cell */ 458 depthSize[2] = 4*(fMax - fStart) + 12*(cMax - cStart); /* Every face is split into 4 faces, and 12 faces are added for each cell */ 459 depthSize[3] = 8*(cMax - cStart); /* Every cell split into 8 cells */ 460 /* Quadrilateral Prisms */ 461 depthSize[0] += 0; /* No hybrid vertices */ 462 depthSize[1] += (eEnd - eMax) + (fEnd - fMax) + (cEnd - cMax); /* Every hybrid edge remains, 1 edge for every hybrid face and hybrid cell */ 463 depthSize[2] += 2*(fEnd - fMax) + 4*(cEnd - cMax); /* Every hybrid face split into 2 faces and 4 faces are added for each hybrid cell */ 464 depthSize[3] += 4*(cEnd - cMax); /* Every hybrid cell split into 4 cells */ 465 break; 466 default: 467 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 468 } 469 PetscFunctionReturn(0); 470 } 471 472 /* Return triangle edge for orientation o, if it is r for o == 0 */ 473 PETSC_STATIC_INLINE PetscInt GetTriEdge_Static(PetscInt o, PetscInt r) { 474 return (o < 0 ? 2-(o+r) : o+r)%3; 475 } 476 PETSC_STATIC_INLINE PetscInt GetTriEdgeInverse_Static(PetscInt o, PetscInt s) { 477 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 478 } 479 480 /* Return triangle subface for orientation o, if it is r for o == 0 */ 481 PETSC_STATIC_INLINE PetscInt GetTriSubface_Static(PetscInt o, PetscInt r) { 482 return (o < 0 ? 3-(o+r) : o+r)%3; 483 } 484 PETSC_STATIC_INLINE PetscInt GetTriSubfaceInverse_Static(PetscInt o, PetscInt s) { 485 return (o < 0 ? 3-(o+s) : 3+s-o)%3; 486 } 487 488 /* Return the interior edge number connecting the midpoints of the triangle edges r 489 and r+1 in the transitive closure for triangle orientation o */ 490 PETSC_STATIC_INLINE PetscInt GetTriMidEdge_Static(PetscInt o, PetscInt r) { 491 return (o < 0 ? 1-(o+r) : o+r)%3; 492 } 493 PETSC_STATIC_INLINE PetscInt GetTriMidEdgeInverse_Static(PetscInt o, PetscInt s) { 494 return (o < 0 ? 1-(o+s) : 3+s-o)%3; 495 } 496 497 /* Return the interior edge number connecting the midpoint of the triangle edge r 498 (in the transitive closure) and the vertex in the interior of the face for triangle orientation o */ 499 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdge_Static(PetscInt o, PetscInt r) { 500 return (o < 0 ? 2-(o+r) : o+r)%3; 501 } 502 PETSC_STATIC_INLINE PetscInt GetTriInteriorEdgeInverse_Static(PetscInt o, PetscInt s) { 503 return (o < 0 ? 2-(o+s) : 3+s-o)%3; 504 } 505 506 /* Return quad edge for orientation o, if it is r for o == 0 */ 507 PETSC_STATIC_INLINE PetscInt GetQuadEdge_Static(PetscInt o, PetscInt r) { 508 return (o < 0 ? 3-(o+r) : o+r)%4; 509 } 510 PETSC_STATIC_INLINE PetscInt GetQuadEdgeInverse_Static(PetscInt o, PetscInt s) { 511 return (o < 0 ? 3-(o+s) : 4+s-o)%4; 512 } 513 514 /* Return quad subface for orientation o, if it is r for o == 0 */ 515 PETSC_STATIC_INLINE PetscInt GetQuadSubface_Static(PetscInt o, PetscInt r) { 516 return (o < 0 ? 4-(o+r) : o+r)%4; 517 } 518 PETSC_STATIC_INLINE PetscInt GetQuadSubfaceInverse_Static(PetscInt o, PetscInt s) { 519 return (o < 0 ? 4-(o+s) : 4+s-o)%4; 520 } 521 522 static PetscErrorCode DMLabelSetStratumBounds(DMLabel label, PetscInt value, PetscInt cStart, PetscInt cEnd) 523 { 524 IS cIS; 525 PetscErrorCode ierr; 526 527 PetscFunctionBegin; 528 ierr = ISCreateStride(PETSC_COMM_SELF, cEnd - cStart, cStart, 1, &cIS);CHKERRQ(ierr); 529 ierr = DMLabelSetStratumIS(label, value, cIS);CHKERRQ(ierr); 530 ierr = ISDestroy(&cIS);CHKERRQ(ierr); 531 PetscFunctionReturn(0); 532 } 533 534 static PetscErrorCode CellRefinerSetConeSizes(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 535 { 536 PetscInt depth, cStart, cStartNew, cEnd, cEndNew, cMax, c, vStart, vStartNew, vEnd, vEndNew, vMax, v, fStart, fStartNew, fEnd, fEndNew, fMax, f, eStart, eStartNew, eEnd, eEndNew, eMax, e, r; 537 DMLabel depthLabel, celltypeLabel; 538 PetscErrorCode ierr; 539 540 PetscFunctionBegin; 541 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 542 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 543 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 544 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 545 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 546 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 547 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 548 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 549 ierr = DMCreateLabel(rdm,"depth");CHKERRQ(ierr); 550 ierr = DMPlexGetDepthLabel(rdm,&depthLabel);CHKERRQ(ierr); 551 ierr = DMLabelSetStratumBounds(depthLabel, 0, vStartNew, vEndNew);CHKERRQ(ierr); 552 if (depth > 2) ierr = DMLabelSetStratumBounds(depthLabel, 1, eStartNew, eEndNew);CHKERRQ(ierr); 553 if (depth > 1) ierr = DMLabelSetStratumBounds(depthLabel, depth - 1, fStartNew, fEndNew);CHKERRQ(ierr); 554 if (depth > 0) ierr = DMLabelSetStratumBounds(depthLabel, depth, cStartNew, cEndNew);CHKERRQ(ierr); 555 { 556 DM_Plex *plex = (DM_Plex *) rdm->data; 557 ierr = PetscObjectStateGet((PetscObject) depthLabel, &plex->depthState);CHKERRQ(ierr); 558 } 559 if (!refiner) PetscFunctionReturn(0); 560 switch (refiner) { 561 case REFINER_SIMPLEX_1D: 562 /* All cells have 2 vertices */ 563 for (c = cStart; c < cEnd; ++c) { 564 for (r = 0; r < 2; ++r) { 565 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 566 567 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 568 } 569 } 570 /* Old vertices have identical supports */ 571 for (v = vStart; v < vEnd; ++v) { 572 const PetscInt newp = vStartNew + (v - vStart); 573 PetscInt size; 574 575 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 576 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 577 } 578 /* Cell vertices have support 2 */ 579 for (c = cStart; c < cEnd; ++c) { 580 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 581 582 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 583 } 584 break; 585 case REFINER_SIMPLEX_2D: 586 /* All cells have 3 faces */ 587 for (c = cStart; c < cEnd; ++c) { 588 for (r = 0; r < 4; ++r) { 589 const PetscInt newp = (c - cStart)*4 + r; 590 591 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 592 } 593 } 594 /* Split faces have 2 vertices and the same cells as the parent */ 595 for (f = fStart; f < fEnd; ++f) { 596 for (r = 0; r < 2; ++r) { 597 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 598 PetscInt size; 599 600 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 601 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 602 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 603 } 604 } 605 /* Interior faces have 2 vertices and 2 cells */ 606 for (c = cStart; c < cEnd; ++c) { 607 for (r = 0; r < 3; ++r) { 608 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 609 610 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 611 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 612 } 613 } 614 /* Old vertices have identical supports */ 615 for (v = vStart; v < vEnd; ++v) { 616 const PetscInt newp = vStartNew + (v - vStart); 617 PetscInt size; 618 619 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 620 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 621 } 622 /* Face vertices have 2 + cells*2 supports */ 623 for (f = fStart; f < fEnd; ++f) { 624 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 625 PetscInt size; 626 627 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 628 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2);CHKERRQ(ierr); 629 } 630 break; 631 case REFINER_SIMPLEX_TO_HEX_2D: 632 /* All cells have 4 faces */ 633 for (c = cStart; c < cEnd; ++c) { 634 for (r = 0; r < 3; ++r) { 635 const PetscInt newp = (c - cStart)*3 + r; 636 637 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 638 } 639 } 640 /* Split faces have 2 vertices and the same cells as the parent */ 641 for (f = fStart; f < fEnd; ++f) { 642 for (r = 0; r < 2; ++r) { 643 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 644 PetscInt size; 645 646 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 647 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 648 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 649 } 650 } 651 /* Interior faces have 2 vertices and 2 cells */ 652 for (c = cStart; c < cEnd; ++c) { 653 for (r = 0; r < 3; ++r) { 654 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 655 656 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 657 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 658 } 659 } 660 /* Old vertices have identical supports */ 661 for (v = vStart; v < vEnd; ++v) { 662 const PetscInt newp = vStartNew + (v - vStart); 663 PetscInt size; 664 665 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 666 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 667 } 668 /* Split-face vertices have cells + 2 supports */ 669 for (f = fStart; f < fEnd; ++f) { 670 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 671 PetscInt size; 672 673 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 674 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 675 } 676 /* Interior vertices have 3 supports */ 677 for (c = cStart; c < cEnd; ++c) { 678 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 679 680 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 681 } 682 break; 683 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 684 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 685 /* the mesh is no longer hybrid */ 686 cMax = PetscMin(cEnd, cMax); 687 /* All cells have 4 faces */ 688 for (c = cStart; c < cMax; ++c) { 689 for (r = 0; r < 3; ++r) { 690 const PetscInt newp = (c - cStart)*3 + r; 691 692 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 693 } 694 } 695 for (c = cMax; c < cEnd; ++c) { 696 for (r = 0; r < 4; ++r) { 697 const PetscInt newp = (cMax - cStart)*3 + (c - cMax)*4 + r; 698 699 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 700 } 701 } 702 /* Split faces have 2 vertices and the same cells as the parent */ 703 for (f = fStart; f < fEnd; ++f) { 704 for (r = 0; r < 2; ++r) { 705 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 706 PetscInt size; 707 708 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 709 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 710 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 711 } 712 } 713 /* Interior faces have 2 vertices and 2 cells */ 714 for (c = cStart; c < cMax; ++c) { 715 for (r = 0; r < 3; ++r) { 716 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 717 718 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 719 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 720 } 721 } 722 /* Hybrid interior faces have 2 vertices and 2 cells */ 723 for (c = cMax; c < cEnd; ++c) { 724 for (r = 0; r < 4; ++r) { 725 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 726 727 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 728 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 729 } 730 } 731 /* Old vertices have identical supports */ 732 for (v = vStart; v < vEnd; ++v) { 733 const PetscInt newp = vStartNew + (v - vStart); 734 PetscInt size; 735 736 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 737 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 738 } 739 /* Split-face vertices have cells + 2 supports */ 740 for (f = fStart; f < fEnd; ++f) { 741 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 742 PetscInt size; 743 744 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 745 ierr = DMPlexSetSupportSize(rdm, newp, size + 2);CHKERRQ(ierr); 746 } 747 /* Interior vertices have 3 supports */ 748 for (c = cStart; c < cMax; ++c) { 749 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 750 751 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 752 } 753 /* Hybrid interior vertices have 4 supports */ 754 for (c = cMax; c < cEnd; ++c) { 755 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 756 757 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 758 } 759 break; 760 case REFINER_HEX_2D: 761 /* All cells have 4 faces */ 762 for (c = cStart; c < cEnd; ++c) { 763 for (r = 0; r < 4; ++r) { 764 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 765 766 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 767 } 768 } 769 /* Split faces have 2 vertices and the same cells as the parent */ 770 for (f = fStart; f < fEnd; ++f) { 771 for (r = 0; r < 2; ++r) { 772 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 773 PetscInt size; 774 775 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 776 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 777 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 778 } 779 } 780 /* Interior faces have 2 vertices and 2 cells */ 781 for (c = cStart; c < cEnd; ++c) { 782 for (r = 0; r < 4; ++r) { 783 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 784 785 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 786 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 787 } 788 } 789 /* Old vertices have identical supports */ 790 for (v = vStart; v < vEnd; ++v) { 791 const PetscInt newp = vStartNew + (v - vStart); 792 PetscInt size; 793 794 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 795 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 796 } 797 /* Face vertices have 2 + cells supports */ 798 for (f = fStart; f < fEnd; ++f) { 799 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 800 PetscInt size; 801 802 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 803 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 804 } 805 /* Cell vertices have 4 supports */ 806 for (c = cStart; c < cEnd; ++c) { 807 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 808 809 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 810 } 811 break; 812 case REFINER_HYBRID_SIMPLEX_2D: 813 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 814 cMax = PetscMin(cEnd, cMax); 815 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 816 fMax = PetscMin(fEnd, fMax); 817 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 818 /* Interior cells have 3 faces */ 819 for (c = cStart; c < cMax; ++c) { 820 for (r = 0; r < 4; ++r) { 821 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 822 823 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 824 } 825 } 826 /* Hybrid cells have 4 faces */ 827 for (c = cMax; c < cEnd; ++c) { 828 for (r = 0; r < 2; ++r) { 829 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 830 831 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 832 } 833 } 834 /* Interior split faces have 2 vertices and the same cells as the parent */ 835 for (f = fStart; f < fMax; ++f) { 836 for (r = 0; r < 2; ++r) { 837 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 838 PetscInt size; 839 840 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 841 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 842 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 843 } 844 } 845 /* Interior cell faces have 2 vertices and 2 cells */ 846 for (c = cStart; c < cMax; ++c) { 847 for (r = 0; r < 3; ++r) { 848 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 849 850 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 851 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 852 } 853 } 854 /* Hybrid faces have 2 vertices and the same cells */ 855 for (f = fMax; f < fEnd; ++f) { 856 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 857 PetscInt size; 858 859 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 860 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 861 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 862 } 863 /* Hybrid cell faces have 2 vertices and 2 cells */ 864 for (c = cMax; c < cEnd; ++c) { 865 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 866 867 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 868 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 869 } 870 /* Old vertices have identical supports */ 871 for (v = vStart; v < vEnd; ++v) { 872 const PetscInt newp = vStartNew + (v - vStart); 873 PetscInt size; 874 875 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 876 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 877 } 878 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 879 for (f = fStart; f < fMax; ++f) { 880 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 881 const PetscInt *support; 882 PetscInt size, newSize = 2, s; 883 884 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 885 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 886 for (s = 0; s < size; ++s) { 887 if (support[s] >= cMax) newSize += 1; 888 else newSize += 2; 889 } 890 ierr = DMPlexSetSupportSize(rdm, newp, newSize);CHKERRQ(ierr); 891 } 892 break; 893 case REFINER_HYBRID_HEX_2D: 894 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 895 cMax = PetscMin(cEnd, cMax); 896 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 897 fMax = PetscMin(fEnd, fMax); 898 ierr = DMPlexSetHybridBounds(rdm, cStartNew + (cMax - cStart)*4, fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 899 /* Interior cells have 4 faces */ 900 for (c = cStart; c < cMax; ++c) { 901 for (r = 0; r < 4; ++r) { 902 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 903 904 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 905 } 906 } 907 /* Hybrid cells have 4 faces */ 908 for (c = cMax; c < cEnd; ++c) { 909 for (r = 0; r < 2; ++r) { 910 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2 + r; 911 912 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 913 } 914 } 915 /* Interior split faces have 2 vertices and the same cells as the parent */ 916 for (f = fStart; f < fMax; ++f) { 917 for (r = 0; r < 2; ++r) { 918 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 919 PetscInt size; 920 921 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 922 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 923 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 924 } 925 } 926 /* Interior cell faces have 2 vertices and 2 cells */ 927 for (c = cStart; c < cMax; ++c) { 928 for (r = 0; r < 4; ++r) { 929 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 930 931 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 932 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 933 } 934 } 935 /* Hybrid faces have 2 vertices and the same cells */ 936 for (f = fMax; f < fEnd; ++f) { 937 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 938 PetscInt size; 939 940 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 941 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 942 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 943 } 944 /* Hybrid cell faces have 2 vertices and 2 cells */ 945 for (c = cMax; c < cEnd; ++c) { 946 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 947 948 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 949 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 950 } 951 /* Old vertices have identical supports */ 952 for (v = vStart; v < vEnd; ++v) { 953 const PetscInt newp = vStartNew + (v - vStart); 954 PetscInt size; 955 956 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 957 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 958 } 959 /* Face vertices have 2 + cells supports */ 960 for (f = fStart; f < fMax; ++f) { 961 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 962 PetscInt size; 963 964 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 965 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 966 } 967 /* Cell vertices have 4 supports */ 968 for (c = cStart; c < cMax; ++c) { 969 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 970 971 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 972 } 973 break; 974 case REFINER_SIMPLEX_3D: 975 /* All cells have 4 faces */ 976 for (c = cStart; c < cEnd; ++c) { 977 for (r = 0; r < 8; ++r) { 978 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 979 980 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 981 } 982 } 983 /* Split faces have 3 edges and the same cells as the parent */ 984 for (f = fStart; f < fEnd; ++f) { 985 for (r = 0; r < 4; ++r) { 986 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 987 PetscInt size; 988 989 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 990 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 991 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 992 } 993 } 994 /* Interior cell faces have 3 edges and 2 cells */ 995 for (c = cStart; c < cEnd; ++c) { 996 for (r = 0; r < 8; ++r) { 997 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + r; 998 999 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 1000 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1001 } 1002 } 1003 /* Split edges have 2 vertices and the same faces */ 1004 for (e = eStart; e < eEnd; ++e) { 1005 for (r = 0; r < 2; ++r) { 1006 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1007 PetscInt size; 1008 1009 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1010 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1011 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1012 } 1013 } 1014 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 1015 for (f = fStart; f < fEnd; ++f) { 1016 for (r = 0; r < 3; ++r) { 1017 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1018 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 1019 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 1020 1021 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1022 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1023 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1024 for (s = 0; s < supportSize; ++s) { 1025 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1026 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1027 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1028 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1029 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 1030 er = GetTriMidEdgeInverse_Static(ornt[c], r); 1031 if (er == eint[c]) { 1032 intFaces += 1; 1033 } else { 1034 intFaces += 2; 1035 } 1036 } 1037 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 1038 } 1039 } 1040 /* Interior cell edges have 2 vertices and 4 faces */ 1041 for (c = cStart; c < cEnd; ++c) { 1042 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 1043 1044 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1045 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1046 } 1047 /* Old vertices have identical supports */ 1048 for (v = vStart; v < vEnd; ++v) { 1049 const PetscInt newp = vStartNew + (v - vStart); 1050 PetscInt size; 1051 1052 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1053 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1054 } 1055 /* Edge vertices have 2 + faces*2 + cells*0/1 supports */ 1056 for (e = eStart; e < eEnd; ++e) { 1057 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1058 PetscInt size, *star = NULL, starSize, s, cellSize = 0; 1059 1060 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1061 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1062 for (s = 0; s < starSize*2; s += 2) { 1063 const PetscInt *cone, *ornt; 1064 PetscInt e01, e23; 1065 1066 if ((star[s] >= cStart) && (star[s] < cEnd)) { 1067 /* Check edge 0-1 */ 1068 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1069 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1070 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1071 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1072 /* Check edge 2-3 */ 1073 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1074 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1075 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1076 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1077 if ((e01 == e) || (e23 == e)) ++cellSize; 1078 } 1079 } 1080 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1081 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size*2 + cellSize);CHKERRQ(ierr); 1082 } 1083 break; 1084 case REFINER_HYBRID_SIMPLEX_3D: 1085 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 8*(cMax - cStart), 1086 eStartNew + 2*(eMax - eStart) + 3*(fMax - fStart) + (cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1087 /* Interior cells have 4 faces */ 1088 for (c = cStart; c < cMax; ++c) { 1089 for (r = 0; r < 8; ++r) { 1090 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1091 1092 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1093 } 1094 } 1095 /* Hybrid cells have 5 faces */ 1096 for (c = cMax; c < cEnd; ++c) { 1097 for (r = 0; r < 4; ++r) { 1098 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1099 1100 ierr = DMPlexSetConeSize(rdm, newp, 5);CHKERRQ(ierr); 1101 } 1102 } 1103 /* Interior split faces have 3 edges and the same cells as the parent */ 1104 for (f = fStart; f < fMax; ++f) { 1105 for (r = 0; r < 4; ++r) { 1106 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1107 PetscInt size; 1108 1109 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 1110 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1111 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1112 } 1113 } 1114 /* Interior cell faces have 3 edges and 2 cells */ 1115 for (c = cStart; c < cMax; ++c) { 1116 for (r = 0; r < 8; ++r) { 1117 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + r; 1118 1119 ierr = DMPlexSetConeSize(rdm, newp, 3);CHKERRQ(ierr); 1120 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1121 } 1122 } 1123 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1124 for (f = fMax; f < fEnd; ++f) { 1125 for (r = 0; r < 2; ++r) { 1126 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 1127 PetscInt size; 1128 1129 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1130 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1131 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1132 } 1133 } 1134 /* Hybrid cells faces have 4 edges and 2 cells */ 1135 for (c = cMax; c < cEnd; ++c) { 1136 for (r = 0; r < 3; ++r) { 1137 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1138 1139 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1140 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1141 } 1142 } 1143 /* Interior split edges have 2 vertices and the same faces */ 1144 for (e = eStart; e < eMax; ++e) { 1145 for (r = 0; r < 2; ++r) { 1146 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1147 PetscInt size; 1148 1149 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1150 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1151 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1152 } 1153 } 1154 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 1155 for (f = fStart; f < fMax; ++f) { 1156 for (r = 0; r < 3; ++r) { 1157 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1158 const PetscInt *cone, *ornt, *support, eint[4] = {1, 0, 2, 0}; 1159 PetscInt coneSize, c, supportSize, s, er, intFaces = 0; 1160 1161 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1162 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1163 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1164 for (s = 0; s < supportSize; ++s) { 1165 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1166 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1167 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1168 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 1169 if (support[s] < cMax) { 1170 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 1171 er = GetTriMidEdgeInverse_Static(ornt[c], r); 1172 if (er == eint[c]) { 1173 intFaces += 1; 1174 } else { 1175 intFaces += 2; 1176 } 1177 } else { 1178 intFaces += 1; 1179 } 1180 } 1181 ierr = DMPlexSetSupportSize(rdm, newp, 2+intFaces);CHKERRQ(ierr); 1182 } 1183 } 1184 /* Interior cell edges have 2 vertices and 4 faces */ 1185 for (c = cStart; c < cMax; ++c) { 1186 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 1187 1188 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1189 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1190 } 1191 /* Hybrid edges have 2 vertices and the same faces */ 1192 for (e = eMax; e < eEnd; ++e) { 1193 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 1194 PetscInt size; 1195 1196 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1197 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1198 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1199 } 1200 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 1201 for (f = fMax; f < fEnd; ++f) { 1202 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 1203 PetscInt size; 1204 1205 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1206 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1207 ierr = DMPlexSetSupportSize(rdm, newp, 2+2*size);CHKERRQ(ierr); 1208 } 1209 /* Interior vertices have identical supports */ 1210 for (v = vStart; v < vEnd; ++v) { 1211 const PetscInt newp = vStartNew + (v - vStart); 1212 PetscInt size; 1213 1214 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1215 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1216 } 1217 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 1218 for (e = eStart; e < eMax; ++e) { 1219 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1220 const PetscInt *support; 1221 PetscInt size, *star = NULL, starSize, s, faceSize = 0, cellSize = 0; 1222 1223 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1224 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 1225 for (s = 0; s < size; ++s) { 1226 if (support[s] < fMax) faceSize += 2; 1227 else faceSize += 1; 1228 } 1229 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1230 for (s = 0; s < starSize*2; s += 2) { 1231 const PetscInt *cone, *ornt; 1232 PetscInt e01, e23; 1233 1234 if ((star[s] >= cStart) && (star[s] < cMax)) { 1235 /* Check edge 0-1 */ 1236 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1237 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1238 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 1239 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 1240 /* Check edge 2-3 */ 1241 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 1242 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 1243 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 1244 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 1245 if ((e01 == e) || (e23 == e)) ++cellSize; 1246 } 1247 } 1248 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 1249 ierr = DMPlexSetSupportSize(rdm, newp, 2 + faceSize + cellSize);CHKERRQ(ierr); 1250 } 1251 break; 1252 case REFINER_SIMPLEX_TO_HEX_3D: 1253 /* All cells have 6 faces */ 1254 for (c = cStart; c < cEnd; ++c) { 1255 for (r = 0; r < 4; ++r) { 1256 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1257 1258 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1259 } 1260 } 1261 /* Split faces have 4 edges and the same cells as the parent */ 1262 for (f = fStart; f < fEnd; ++f) { 1263 for (r = 0; r < 3; ++r) { 1264 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1265 PetscInt size; 1266 1267 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1268 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1269 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1270 } 1271 } 1272 /* Interior cell faces have 4 edges and 2 cells */ 1273 for (c = cStart; c < cEnd; ++c) { 1274 for (r = 0; r < 6; ++r) { 1275 const PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + r; 1276 1277 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1278 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1279 } 1280 } 1281 /* Split edges have 2 vertices and the same faces */ 1282 for (e = eStart; e < eEnd; ++e) { 1283 for (r = 0; r < 2; ++r) { 1284 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1285 PetscInt size; 1286 1287 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1288 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1289 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1290 } 1291 } 1292 /* Face edges have 2 vertices and 2 + cell faces supports */ 1293 for (f = fStart; f < fEnd; ++f) { 1294 for (r = 0; r < 3; ++r) { 1295 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 1296 PetscInt size; 1297 1298 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1299 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1300 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1301 } 1302 } 1303 /* Interior cell edges have 2 vertices and 3 faces */ 1304 for (c = cStart; c < cEnd; ++c) { 1305 for (r = 0; r < 4; ++r) { 1306 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 1307 1308 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1309 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1310 } 1311 } 1312 /* Old vertices have identical supports */ 1313 for (v = vStart; v < vEnd; ++v) { 1314 const PetscInt newp = vStartNew + (v - vStart); 1315 PetscInt size; 1316 1317 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1318 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1319 } 1320 /* Edge vertices have 2 + faces supports */ 1321 for (e = eStart; e < eEnd; ++e) { 1322 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1323 PetscInt size; 1324 1325 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1326 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1327 } 1328 /* Face vertices have 3 + cells supports */ 1329 for (f = fStart; f < fEnd; ++f) { 1330 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 1331 PetscInt size; 1332 1333 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1334 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1335 } 1336 /* Interior cell vertices have 4 supports */ 1337 for (c = cStart; c < cEnd; ++c) { 1338 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + fEnd - fStart + c - cStart; 1339 1340 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1341 } 1342 break; 1343 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 1344 /* the mesh is no longer hybrid */ 1345 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 1346 cMax = PetscMin(cEnd, cMax); 1347 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 1348 fMax = PetscMin(fEnd, fMax); 1349 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 1350 eMax = PetscMin(eEnd, eMax); 1351 /* All cells have 6 faces */ 1352 for (c = cStart; c < cMax; ++c) { 1353 for (r = 0; r < 4; ++r) { 1354 const PetscInt newp = cStartNew + (c - cStart)*4 + r; 1355 1356 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1357 } 1358 } 1359 for (c = cMax; c < cEnd; ++c) { 1360 for (r = 0; r < 3; ++r) { 1361 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + r; 1362 1363 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1364 } 1365 } 1366 /* Interior split faces have 4 edges and the same cells as the parent */ 1367 for (f = fStart; f < fMax; ++f) { 1368 for (r = 0; r < 3; ++r) { 1369 const PetscInt newp = fStartNew + (f - fStart)*3 + r; 1370 PetscInt size; 1371 1372 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1373 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1374 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1375 } 1376 } 1377 /* Interior cell faces have 4 edges and 2 cells */ 1378 for (c = cStart; c < cMax; ++c) { 1379 for (r = 0; r < 6; ++r) { 1380 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + r; 1381 1382 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1383 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1384 } 1385 } 1386 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1387 for (f = fMax; f < fEnd; ++f) { 1388 for (r = 0; r < 2; ++r) { 1389 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2 + r; 1390 PetscInt size; 1391 1392 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1393 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1394 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1395 } 1396 } 1397 /* Hybrid cell faces have 4 edges and 2 cells */ 1398 for (c = cMax; c < cEnd; ++c) { 1399 for (r = 0; r < 3; ++r) { 1400 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + r; 1401 1402 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1403 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1404 } 1405 } 1406 /* Interior split edges have 2 vertices and the same faces */ 1407 for (e = eStart; e < eMax; ++e) { 1408 for (r = 0; r < 2; ++r) { 1409 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1410 PetscInt size; 1411 1412 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1413 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1414 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1415 } 1416 } 1417 /* Interior face edges have 2 vertices and 2 + cell faces supports */ 1418 for (f = fStart; f < fMax; ++f) { 1419 for (r = 0; r < 3; ++r) { 1420 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 1421 PetscInt size; 1422 1423 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1424 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1425 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1426 } 1427 } 1428 /* Interior cell edges have 2 vertices and 3 faces */ 1429 for (c = cStart; c < cMax; ++c) { 1430 for (r = 0; r < 4; ++r) { 1431 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 1432 1433 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1434 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1435 } 1436 } 1437 /* Hybrid edges have 2 vertices and the same faces */ 1438 for (e = eMax; e < eEnd; ++e) { 1439 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 1440 PetscInt size; 1441 1442 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1443 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1444 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1445 } 1446 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1447 for (f = fMax; f < fEnd; ++f) { 1448 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 1449 PetscInt size; 1450 1451 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1452 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1453 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1454 } 1455 /* Hybrid cell edges have 2 vertices and 3 faces */ 1456 for (c = cMax; c < cEnd; ++c) { 1457 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1458 1459 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1460 ierr = DMPlexSetSupportSize(rdm, newp, 3);CHKERRQ(ierr); 1461 } 1462 /* Old vertices have identical supports */ 1463 for (v = vStart; v < vEnd; ++v) { 1464 const PetscInt newp = vStartNew + (v - vStart); 1465 PetscInt size; 1466 1467 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1468 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1469 } 1470 /* Interior edge vertices have 2 + faces supports */ 1471 for (e = eStart; e < eMax; ++e) { 1472 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1473 PetscInt size; 1474 1475 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1476 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1477 } 1478 /* Interior face vertices have 3 + cells supports */ 1479 for (f = fStart; f < fMax; ++f) { 1480 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 1481 PetscInt size; 1482 1483 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1484 ierr = DMPlexSetSupportSize(rdm, newp, 3 + size);CHKERRQ(ierr); 1485 } 1486 /* Interior cell vertices have 4 supports */ 1487 for (c = cStart; c < cMax; ++c) { 1488 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 1489 1490 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1491 } 1492 break; 1493 case REFINER_HEX_3D: 1494 /* All cells have 6 faces */ 1495 for (c = cStart; c < cEnd; ++c) { 1496 for (r = 0; r < 8; ++r) { 1497 const PetscInt newp = (c - cStart)*8 + r; 1498 1499 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1500 } 1501 } 1502 /* Split faces have 4 edges and the same cells as the parent */ 1503 for (f = fStart; f < fEnd; ++f) { 1504 for (r = 0; r < 4; ++r) { 1505 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1506 PetscInt size; 1507 1508 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1509 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1510 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1511 } 1512 } 1513 /* Interior faces have 4 edges and 2 cells */ 1514 for (c = cStart; c < cEnd; ++c) { 1515 for (r = 0; r < 12; ++r) { 1516 const PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 1517 1518 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1519 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1520 } 1521 } 1522 /* Split edges have 2 vertices and the same faces as the parent */ 1523 for (e = eStart; e < eEnd; ++e) { 1524 for (r = 0; r < 2; ++r) { 1525 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1526 PetscInt size; 1527 1528 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1529 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1530 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1531 } 1532 } 1533 /* Face edges have 2 vertices and 2+cells faces */ 1534 for (f = fStart; f < fEnd; ++f) { 1535 for (r = 0; r < 4; ++r) { 1536 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 1537 PetscInt size; 1538 1539 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1540 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1541 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1542 } 1543 } 1544 /* Cell edges have 2 vertices and 4 faces */ 1545 for (c = cStart; c < cEnd; ++c) { 1546 for (r = 0; r < 6; ++r) { 1547 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 1548 1549 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1550 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1551 } 1552 } 1553 /* Old vertices have identical supports */ 1554 for (v = vStart; v < vEnd; ++v) { 1555 const PetscInt newp = vStartNew + (v - vStart); 1556 PetscInt size; 1557 1558 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1559 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1560 } 1561 /* Edge vertices have 2 + faces supports */ 1562 for (e = eStart; e < eEnd; ++e) { 1563 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1564 PetscInt size; 1565 1566 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1567 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1568 } 1569 /* Face vertices have 4 + cells supports */ 1570 for (f = fStart; f < fEnd; ++f) { 1571 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 1572 PetscInt size; 1573 1574 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1575 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1576 } 1577 /* Cell vertices have 6 supports */ 1578 for (c = cStart; c < cEnd; ++c) { 1579 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 1580 1581 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1582 } 1583 break; 1584 case REFINER_HYBRID_HEX_3D: 1585 ierr = DMPlexSetHybridBounds(rdm, cStartNew + 8*(cMax-cStart), fStartNew + 4*(fMax - fStart) + 12*(cMax - cStart), 1586 eStartNew + 2*(eMax - eStart) + 4*(fMax - fStart) + 6*(cMax - cStart), PETSC_DETERMINE);CHKERRQ(ierr); 1587 /* Interior cells have 6 faces */ 1588 for (c = cStart; c < cMax; ++c) { 1589 for (r = 0; r < 8; ++r) { 1590 const PetscInt newp = cStartNew + (c - cStart)*8 + r; 1591 1592 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1593 } 1594 } 1595 /* Hybrid cells have 6 faces */ 1596 for (c = cMax; c < cEnd; ++c) { 1597 for (r = 0; r < 4; ++r) { 1598 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + r; 1599 1600 ierr = DMPlexSetConeSize(rdm, newp, 6);CHKERRQ(ierr); 1601 } 1602 } 1603 /* Interior split faces have 4 edges and the same cells as the parent */ 1604 for (f = fStart; f < fMax; ++f) { 1605 for (r = 0; r < 4; ++r) { 1606 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 1607 PetscInt size; 1608 1609 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1610 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1611 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1612 } 1613 } 1614 /* Interior cell faces have 4 edges and 2 cells */ 1615 for (c = cStart; c < cMax; ++c) { 1616 for (r = 0; r < 12; ++r) { 1617 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 1618 1619 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1620 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1621 } 1622 } 1623 /* Hybrid split faces have 4 edges and the same cells as the parent */ 1624 for (f = fMax; f < fEnd; ++f) { 1625 for (r = 0; r < 2; ++r) { 1626 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 1627 PetscInt size; 1628 1629 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1630 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1631 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1632 } 1633 } 1634 /* Hybrid cells faces have 4 edges and 2 cells */ 1635 for (c = cMax; c < cEnd; ++c) { 1636 for (r = 0; r < 4; ++r) { 1637 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + r; 1638 1639 ierr = DMPlexSetConeSize(rdm, newp, 4);CHKERRQ(ierr); 1640 ierr = DMPlexSetSupportSize(rdm, newp, 2);CHKERRQ(ierr); 1641 } 1642 } 1643 /* Interior split edges have 2 vertices and the same faces as the parent */ 1644 for (e = eStart; e < eMax; ++e) { 1645 for (r = 0; r < 2; ++r) { 1646 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 1647 PetscInt size; 1648 1649 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1650 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1651 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1652 } 1653 } 1654 /* Interior face edges have 2 vertices and 2+cells faces */ 1655 for (f = fStart; f < fMax; ++f) { 1656 for (r = 0; r < 4; ++r) { 1657 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 1658 PetscInt size; 1659 1660 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1661 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1662 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1663 } 1664 } 1665 /* Interior cell edges have 2 vertices and 4 faces */ 1666 for (c = cStart; c < cMax; ++c) { 1667 for (r = 0; r < 6; ++r) { 1668 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 1669 1670 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1671 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1672 } 1673 } 1674 /* Hybrid edges have 2 vertices and the same faces */ 1675 for (e = eMax; e < eEnd; ++e) { 1676 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 1677 PetscInt size; 1678 1679 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1680 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1681 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1682 } 1683 /* Hybrid face edges have 2 vertices and 2+cells faces */ 1684 for (f = fMax; f < fEnd; ++f) { 1685 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 1686 PetscInt size; 1687 1688 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1689 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1690 ierr = DMPlexSetSupportSize(rdm, newp, 2+size);CHKERRQ(ierr); 1691 } 1692 /* Hybrid cell edges have 2 vertices and 4 faces */ 1693 for (c = cMax; c < cEnd; ++c) { 1694 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 1695 1696 ierr = DMPlexSetConeSize(rdm, newp, 2);CHKERRQ(ierr); 1697 ierr = DMPlexSetSupportSize(rdm, newp, 4);CHKERRQ(ierr); 1698 } 1699 /* Interior vertices have identical supports */ 1700 for (v = vStart; v < vEnd; ++v) { 1701 const PetscInt newp = vStartNew + (v - vStart); 1702 PetscInt size; 1703 1704 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1705 ierr = DMPlexSetSupportSize(rdm, newp, size);CHKERRQ(ierr); 1706 } 1707 /* Interior edge vertices have 2 + faces supports */ 1708 for (e = eStart; e < eMax; ++e) { 1709 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 1710 PetscInt size; 1711 1712 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 1713 ierr = DMPlexSetSupportSize(rdm, newp, 2 + size);CHKERRQ(ierr); 1714 } 1715 /* Interior face vertices have 4 + cells supports */ 1716 for (f = fStart; f < fMax; ++f) { 1717 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 1718 PetscInt size; 1719 1720 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 1721 ierr = DMPlexSetSupportSize(rdm, newp, 4 + size);CHKERRQ(ierr); 1722 } 1723 /* Interior cell vertices have 6 supports */ 1724 for (c = cStart; c < cMax; ++c) { 1725 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 1726 1727 ierr = DMPlexSetSupportSize(rdm, newp, 6);CHKERRQ(ierr); 1728 } 1729 break; 1730 default: 1731 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 1732 } 1733 { 1734 DM_Plex *plex = (DM_Plex *) rdm->data; 1735 1736 ierr = DMPlexGetCellTypeLabel(rdm, &celltypeLabel);CHKERRQ(ierr); 1737 ierr = PetscObjectStateGet((PetscObject) celltypeLabel, &plex->celltypeState);CHKERRQ(ierr); 1738 } 1739 PetscFunctionReturn(0); 1740 } 1741 1742 static PetscErrorCode CellRefinerSetCones(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 1743 { 1744 const PetscInt *faces, cellInd[4] = {0, 1, 2, 3}; 1745 PetscInt cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax; 1746 PetscInt cStartNew, cEndNew, cMaxNew, vStartNew, vEndNew, fStartNew, fEndNew, fMaxNew, eStartNew, eEndNew, eMaxNew; 1747 PetscInt depth, maxSupportSize, *supportRef, c, f, e, v, r; 1748 #if defined(PETSC_USE_DEBUG) 1749 PetscInt p; 1750 #endif 1751 PetscErrorCode ierr; 1752 1753 PetscFunctionBegin; 1754 if (!refiner) PetscFunctionReturn(0); 1755 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 1756 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 1757 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 1758 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 1759 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 1760 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 1761 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr); 1762 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, &fEndNew, &eEndNew, &vEndNew);CHKERRQ(ierr); 1763 switch (refiner) { 1764 case REFINER_SIMPLEX_1D: 1765 /* Max support size of refined mesh is 2 */ 1766 ierr = PetscMalloc1(2, &supportRef);CHKERRQ(ierr); 1767 /* All cells have 2 vertices */ 1768 for (c = cStart; c < cEnd; ++c) { 1769 const PetscInt newv = vStartNew + (vEnd - vStart) + (c - cStart); 1770 1771 for (r = 0; r < 2; ++r) { 1772 const PetscInt newp = cStartNew + (c - cStart)*2 + r; 1773 const PetscInt *cone; 1774 PetscInt coneNew[2]; 1775 1776 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1777 coneNew[0] = vStartNew + (cone[0] - vStart); 1778 coneNew[1] = vStartNew + (cone[1] - vStart); 1779 coneNew[(r+1)%2] = newv; 1780 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1781 #if defined(PETSC_USE_DEBUG) 1782 if ((newp < cStartNew) || (newp >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", newp, cStartNew, cEndNew); 1783 for (p = 0; p < 2; ++p) { 1784 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); 1785 } 1786 #endif 1787 } 1788 } 1789 /* Old vertices have identical supports */ 1790 for (v = vStart; v < vEnd; ++v) { 1791 const PetscInt newp = vStartNew + (v - vStart); 1792 const PetscInt *support, *cone; 1793 PetscInt size, s; 1794 1795 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1796 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1797 for (s = 0; s < size; ++s) { 1798 PetscInt r = 0; 1799 1800 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1801 if (cone[1] == v) r = 1; 1802 supportRef[s] = cStartNew + (support[s] - cStart)*2 + r; 1803 } 1804 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1805 #if defined(PETSC_USE_DEBUG) 1806 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1807 for (p = 0; p < size; ++p) { 1808 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); 1809 } 1810 #endif 1811 } 1812 /* Cell vertices have support of 2 cells */ 1813 for (c = cStart; c < cEnd; ++c) { 1814 const PetscInt newp = vStartNew + (vEnd - vStart) + (c - cStart); 1815 1816 supportRef[0] = cStartNew + (c - cStart)*2 + 0; 1817 supportRef[1] = cStartNew + (c - cStart)*2 + 1; 1818 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1819 #if defined(PETSC_USE_DEBUG) 1820 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 1821 for (p = 0; p < 2; ++p) { 1822 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); 1823 } 1824 #endif 1825 } 1826 ierr = PetscFree(supportRef);CHKERRQ(ierr); 1827 break; 1828 case REFINER_SIMPLEX_2D: 1829 /* 1830 2 1831 |\ 1832 | \ 1833 | \ 1834 | \ 1835 | C \ 1836 | \ 1837 | \ 1838 2---1---1 1839 |\ D / \ 1840 | 2 0 \ 1841 |A \ / B \ 1842 0---0-------1 1843 */ 1844 /* All cells have 3 faces */ 1845 for (c = cStart; c < cEnd; ++c) { 1846 const PetscInt newp = cStartNew + (c - cStart)*4; 1847 const PetscInt *cone, *ornt; 1848 PetscInt coneNew[3], orntNew[3]; 1849 1850 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1851 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 1852 /* A triangle */ 1853 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 1854 orntNew[0] = ornt[0]; 1855 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1856 orntNew[1] = -2; 1857 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 1858 orntNew[2] = ornt[2]; 1859 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 1860 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 1861 #if defined(PETSC_USE_DEBUG) 1862 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); 1863 for (p = 0; p < 3; ++p) { 1864 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); 1865 } 1866 #endif 1867 /* B triangle */ 1868 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 1869 orntNew[0] = ornt[0]; 1870 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 1871 orntNew[1] = ornt[1]; 1872 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1873 orntNew[2] = -2; 1874 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 1875 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 1876 #if defined(PETSC_USE_DEBUG) 1877 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); 1878 for (p = 0; p < 3; ++p) { 1879 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); 1880 } 1881 #endif 1882 /* C triangle */ 1883 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1884 orntNew[0] = -2; 1885 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 1886 orntNew[1] = ornt[1]; 1887 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 1888 orntNew[2] = ornt[2]; 1889 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 1890 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 1891 #if defined(PETSC_USE_DEBUG) 1892 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); 1893 for (p = 0; p < 3; ++p) { 1894 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); 1895 } 1896 #endif 1897 /* D triangle */ 1898 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 1899 orntNew[0] = 0; 1900 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 1901 orntNew[1] = 0; 1902 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 1903 orntNew[2] = 0; 1904 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 1905 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 1906 #if defined(PETSC_USE_DEBUG) 1907 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); 1908 for (p = 0; p < 3; ++p) { 1909 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); 1910 } 1911 #endif 1912 } 1913 /* Split faces have 2 vertices and the same cells as the parent */ 1914 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 1915 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 1916 for (f = fStart; f < fEnd; ++f) { 1917 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 1918 1919 for (r = 0; r < 2; ++r) { 1920 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 1921 const PetscInt *cone, *ornt, *support; 1922 PetscInt coneNew[2], coneSize, c, supportSize, s; 1923 1924 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 1925 coneNew[0] = vStartNew + (cone[0] - vStart); 1926 coneNew[1] = vStartNew + (cone[1] - vStart); 1927 coneNew[(r+1)%2] = newv; 1928 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1929 #if defined(PETSC_USE_DEBUG) 1930 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1931 for (p = 0; p < 2; ++p) { 1932 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); 1933 } 1934 #endif 1935 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 1936 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 1937 for (s = 0; s < supportSize; ++s) { 1938 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 1939 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1940 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 1941 for (c = 0; c < coneSize; ++c) { 1942 if (cone[c] == f) break; 1943 } 1944 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 1945 } 1946 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 1947 #if defined(PETSC_USE_DEBUG) 1948 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1949 for (p = 0; p < supportSize; ++p) { 1950 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); 1951 } 1952 #endif 1953 } 1954 } 1955 /* Interior faces have 2 vertices and 2 cells */ 1956 for (c = cStart; c < cEnd; ++c) { 1957 const PetscInt *cone; 1958 1959 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 1960 for (r = 0; r < 3; ++r) { 1961 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 1962 PetscInt coneNew[2]; 1963 PetscInt supportNew[2]; 1964 1965 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 1966 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 1967 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 1968 #if defined(PETSC_USE_DEBUG) 1969 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1970 for (p = 0; p < 2; ++p) { 1971 if ((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); 1972 } 1973 #endif 1974 supportNew[0] = (c - cStart)*4 + (r+1)%3; 1975 supportNew[1] = (c - cStart)*4 + 3; 1976 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 1977 #if defined(PETSC_USE_DEBUG) 1978 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 1979 for (p = 0; p < 2; ++p) { 1980 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); 1981 } 1982 #endif 1983 } 1984 } 1985 /* Old vertices have identical supports */ 1986 for (v = vStart; v < vEnd; ++v) { 1987 const PetscInt newp = vStartNew + (v - vStart); 1988 const PetscInt *support, *cone; 1989 PetscInt size, s; 1990 1991 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 1992 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 1993 for (s = 0; s < size; ++s) { 1994 PetscInt r = 0; 1995 1996 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 1997 if (cone[1] == v) r = 1; 1998 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 1999 } 2000 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2001 #if defined(PETSC_USE_DEBUG) 2002 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2003 for (p = 0; p < size; ++p) { 2004 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); 2005 } 2006 #endif 2007 } 2008 /* Face vertices have 2 + cells*2 supports */ 2009 for (f = fStart; f < fEnd; ++f) { 2010 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2011 const PetscInt *cone, *support; 2012 PetscInt size, s; 2013 2014 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2015 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2016 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2017 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2018 for (s = 0; s < size; ++s) { 2019 PetscInt r = 0; 2020 2021 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2022 if (cone[1] == f) r = 1; 2023 else if (cone[2] == f) r = 2; 2024 supportRef[2+s*2+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 2025 supportRef[2+s*2+1] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2026 } 2027 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2028 #if defined(PETSC_USE_DEBUG) 2029 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2030 for (p = 0; p < 2+size*2; ++p) { 2031 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); 2032 } 2033 #endif 2034 } 2035 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2036 break; 2037 case REFINER_SIMPLEX_TO_HEX_2D: 2038 /* 2039 2 2040 |\ 2041 | \ 2042 | \ 2043 | \ 2044 | C \ 2045 | \ 2046 2 1 2047 |\ / \ 2048 | 2 1 \ 2049 | \/ \ 2050 | | \ 2051 |A | B \ 2052 | 0 \ 2053 | | \ 2054 0---0----------1 2055 */ 2056 /* All cells have 4 faces */ 2057 for (c = cStart; c < cEnd; ++c) { 2058 const PetscInt newp = cStartNew + (c - cStart)*3; 2059 const PetscInt *cone, *ornt; 2060 PetscInt coneNew[4], orntNew[4]; 2061 2062 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2063 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2064 /* A quad */ 2065 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2066 orntNew[0] = ornt[0]; 2067 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2068 orntNew[1] = 0; 2069 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2070 orntNew[2] = -2; 2071 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2072 orntNew[3] = ornt[2]; 2073 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2074 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2075 #if defined(PETSC_USE_DEBUG) 2076 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); 2077 for (p = 0; p < 4; ++p) { 2078 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); 2079 } 2080 #endif 2081 /* B quad */ 2082 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2083 orntNew[0] = ornt[0]; 2084 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2085 orntNew[1] = ornt[1]; 2086 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2087 orntNew[2] = 0; 2088 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2089 orntNew[3] = -2; 2090 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2091 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2092 #if defined(PETSC_USE_DEBUG) 2093 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); 2094 for (p = 0; p < 4; ++p) { 2095 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); 2096 } 2097 #endif 2098 /* C quad */ 2099 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2100 orntNew[0] = ornt[1]; 2101 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2102 orntNew[1] = ornt[2]; 2103 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2104 orntNew[2] = 0; 2105 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2106 orntNew[3] = -2; 2107 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2108 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2109 #if defined(PETSC_USE_DEBUG) 2110 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); 2111 for (p = 0; p < 4; ++p) { 2112 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); 2113 } 2114 #endif 2115 } 2116 /* Split faces have 2 vertices and the same cells as the parent */ 2117 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2118 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2119 for (f = fStart; f < fEnd; ++f) { 2120 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2121 2122 for (r = 0; r < 2; ++r) { 2123 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2124 const PetscInt *cone, *ornt, *support; 2125 PetscInt coneNew[2], coneSize, c, supportSize, s; 2126 2127 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2128 coneNew[0] = vStartNew + (cone[0] - vStart); 2129 coneNew[1] = vStartNew + (cone[1] - vStart); 2130 coneNew[(r+1)%2] = newv; 2131 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2132 #if defined(PETSC_USE_DEBUG) 2133 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2134 for (p = 0; p < 2; ++p) { 2135 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); 2136 } 2137 #endif 2138 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2139 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2140 for (s = 0; s < supportSize; ++s) { 2141 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2142 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2143 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2144 for (c = 0; c < coneSize; ++c) { 2145 if (cone[c] == f) break; 2146 } 2147 supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2148 } 2149 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2150 #if defined(PETSC_USE_DEBUG) 2151 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2152 for (p = 0; p < supportSize; ++p) { 2153 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); 2154 } 2155 #endif 2156 } 2157 } 2158 /* Interior faces have 2 vertices and 2 cells */ 2159 for (c = cStart; c < cEnd; ++c) { 2160 const PetscInt *cone; 2161 2162 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2163 for (r = 0; r < 3; ++r) { 2164 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2165 PetscInt coneNew[2]; 2166 PetscInt supportNew[2]; 2167 2168 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2169 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2170 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2171 #if defined(PETSC_USE_DEBUG) 2172 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2173 for (p = 0; p < 2; ++p) { 2174 if ((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); 2175 } 2176 #endif 2177 supportNew[0] = (c - cStart)*3 + r%3; 2178 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2179 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2180 #if defined(PETSC_USE_DEBUG) 2181 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2182 for (p = 0; p < 2; ++p) { 2183 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); 2184 } 2185 #endif 2186 } 2187 } 2188 /* Old vertices have identical supports */ 2189 for (v = vStart; v < vEnd; ++v) { 2190 const PetscInt newp = vStartNew + (v - vStart); 2191 const PetscInt *support, *cone; 2192 PetscInt size, s; 2193 2194 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2195 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2196 for (s = 0; s < size; ++s) { 2197 PetscInt r = 0; 2198 2199 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2200 if (cone[1] == v) r = 1; 2201 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2202 } 2203 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2204 #if defined(PETSC_USE_DEBUG) 2205 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2206 for (p = 0; p < size; ++p) { 2207 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); 2208 } 2209 #endif 2210 } 2211 /* Split-face vertices have cells + 2 supports */ 2212 for (f = fStart; f < fEnd; ++f) { 2213 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2214 const PetscInt *cone, *support; 2215 PetscInt size, s; 2216 2217 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2218 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2219 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2220 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2221 for (s = 0; s < size; ++s) { 2222 PetscInt r = 0; 2223 2224 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2225 if (cone[1] == f) r = 1; 2226 else if (cone[2] == f) r = 2; 2227 supportRef[2+s+0] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2228 } 2229 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2230 #if defined(PETSC_USE_DEBUG) 2231 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2232 for (p = 0; p < 2+size; ++p) { 2233 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); 2234 } 2235 #endif 2236 } 2237 /* Interior vertices have 3 supports */ 2238 for (c = cStart; c < cEnd; ++c) { 2239 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2240 2241 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2242 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2243 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2244 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2245 } 2246 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2247 break; 2248 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 2249 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2250 cMax = PetscMin(cEnd, cMax); 2251 for (c = cStart; c < cMax; ++c) { 2252 const PetscInt newp = cStartNew + (c - cStart)*3; 2253 const PetscInt *cone, *ornt; 2254 PetscInt coneNew[4], orntNew[4]; 2255 2256 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2257 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2258 /* A quad */ 2259 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2260 orntNew[0] = ornt[0]; 2261 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2262 orntNew[1] = 0; 2263 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2264 orntNew[2] = -2; 2265 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2266 orntNew[3] = ornt[2]; 2267 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2268 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2269 #if defined(PETSC_USE_DEBUG) 2270 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); 2271 for (p = 0; p < 4; ++p) { 2272 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); 2273 } 2274 #endif 2275 /* B quad */ 2276 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2277 orntNew[0] = ornt[0]; 2278 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2279 orntNew[1] = ornt[1]; 2280 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2281 orntNew[2] = 0; 2282 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2283 orntNew[3] = -2; 2284 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2285 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2286 #if defined(PETSC_USE_DEBUG) 2287 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); 2288 for (p = 0; p < 4; ++p) { 2289 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); 2290 } 2291 #endif 2292 /* C quad */ 2293 coneNew[0] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2294 orntNew[0] = ornt[1]; 2295 coneNew[1] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2296 orntNew[1] = ornt[2]; 2297 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2298 orntNew[2] = 0; 2299 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2300 orntNew[3] = -2; 2301 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2302 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2303 #if defined(PETSC_USE_DEBUG) 2304 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); 2305 for (p = 0; p < 4; ++p) { 2306 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); 2307 } 2308 #endif 2309 } 2310 /* 2311 2---------1---------3 2312 | | | 2313 | D 1 C | 2314 | | | 2315 2----2----0----3----3 2316 | | | 2317 | A 0 B | 2318 | | | 2319 0---------0---------1 2320 */ 2321 /* Parent cells are input as prisms but children are quads, since the mesh is no longer hybrid */ 2322 for (c = cMax; c < cEnd; ++c) { 2323 const PetscInt newp = cStartNew + (cMax - cStart)*3 + (c - cMax)*4; 2324 const PetscInt newpt = (cMax - cStart)*3 + (c - cMax)*4; 2325 const PetscInt *cone, *ornt; 2326 PetscInt coneNew[4], orntNew[4]; 2327 2328 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2329 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2330 /* A quad */ 2331 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2332 orntNew[0] = ornt[0]; 2333 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2334 orntNew[1] = 0; 2335 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2336 orntNew[2] = -2; 2337 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2338 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2339 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2340 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2341 #if defined(PETSC_USE_DEBUG) 2342 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); 2343 for (p = 0; p < 4; ++p) { 2344 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); 2345 } 2346 #endif 2347 /* B quad */ 2348 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2349 orntNew[0] = ornt[0]; 2350 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2351 orntNew[1] = ornt[3]; 2352 coneNew[2] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2353 orntNew[2] = 0; 2354 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 0; 2355 orntNew[3] = -2; 2356 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2357 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2358 #if defined(PETSC_USE_DEBUG) 2359 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); 2360 for (p = 0; p < 4; ++p) { 2361 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); 2362 } 2363 #endif 2364 /* C quad */ 2365 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 3; 2366 orntNew[0] = -2; 2367 coneNew[1] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2368 orntNew[1] = ornt[3]; 2369 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2370 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2371 coneNew[3] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2372 orntNew[3] = 0; 2373 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2374 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2375 #if defined(PETSC_USE_DEBUG) 2376 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); 2377 for (p = 0; p < 4; ++p) { 2378 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); 2379 } 2380 #endif 2381 /* D quad */ 2382 coneNew[0] = fStartNew + (fEnd - fStart)*2 + newpt + 2; 2383 orntNew[0] = 0; 2384 coneNew[1] = fStartNew + (fEnd - fStart)*2 + newpt + 1; 2385 orntNew[1] = -2; 2386 coneNew[2] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2387 orntNew[2] = ornt[1] < 0 ? 0 : -2; 2388 coneNew[3] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2389 orntNew[3] = ornt[2] < 0 ? 0 : -2; 2390 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2391 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2392 #if defined(PETSC_USE_DEBUG) 2393 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); 2394 for (p = 0; p < 4; ++p) { 2395 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); 2396 } 2397 #endif 2398 } 2399 /* Split faces have 2 vertices and the same cells as the parent */ 2400 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2401 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2402 for (f = fStart; f < fEnd; ++f) { 2403 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2404 2405 for (r = 0; r < 2; ++r) { 2406 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2407 const PetscInt *cone, *ornt, *support; 2408 PetscInt coneNew[2], coneSize, c, supportSize, s; 2409 2410 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2411 coneNew[0] = vStartNew + (cone[0] - vStart); 2412 coneNew[1] = vStartNew + (cone[1] - vStart); 2413 coneNew[(r+1)%2] = newv; 2414 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2415 #if defined(PETSC_USE_DEBUG) 2416 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2417 for (p = 0; p < 2; ++p) { 2418 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); 2419 } 2420 #endif 2421 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2422 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2423 for (s = 0; s < supportSize; ++s) { 2424 const PetscInt p2q[4][2] = { {0, 1}, 2425 {3, 2}, 2426 {0, 3}, 2427 {1, 2} }; 2428 2429 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2430 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2431 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2432 for (c = 0; c < coneSize; ++c) { 2433 if (cone[c] == f) break; 2434 } 2435 if (coneSize == 3) supportRef[s] = cStartNew + (support[s] - cStart)*3 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2436 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]); 2437 else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2438 } 2439 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2440 #if defined(PETSC_USE_DEBUG) 2441 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2442 for (p = 0; p < supportSize; ++p) { 2443 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); 2444 } 2445 #endif 2446 } 2447 } 2448 /* Interior faces have 2 vertices and 2 cells */ 2449 for (c = cStart; c < cMax; ++c) { 2450 const PetscInt *cone; 2451 2452 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2453 for (r = 0; r < 3; ++r) { 2454 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + r; 2455 PetscInt coneNew[2]; 2456 PetscInt supportNew[2]; 2457 2458 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2459 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2460 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2461 #if defined(PETSC_USE_DEBUG) 2462 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2463 for (p = 0; p < 2; ++p) { 2464 if ((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); 2465 } 2466 #endif 2467 supportNew[0] = (c - cStart)*3 + r%3; 2468 supportNew[1] = (c - cStart)*3 + (r+1)%3; 2469 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2470 #if defined(PETSC_USE_DEBUG) 2471 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2472 for (p = 0; p < 2; ++p) { 2473 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); 2474 } 2475 #endif 2476 } 2477 } 2478 /* Hybrid interior faces have 2 vertices and 2 cells */ 2479 for (c = cMax; c < cEnd; ++c) { 2480 const PetscInt *cone; 2481 PetscInt coneNew[2], supportNew[2]; 2482 2483 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2484 for (r = 0; r < 4; ++r) { 2485 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + r; 2486 2487 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2488 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (cMax - cStart) + (c - cMax); 2489 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2490 #if defined(PETSC_USE_DEBUG) 2491 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2492 for (p = 0; p < 2; ++p) { 2493 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); 2494 } 2495 #endif 2496 if (r==0) { 2497 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2498 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2499 } else if (r==1) { 2500 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2501 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2502 } else if (r==2) { 2503 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 0; 2504 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 3; 2505 } else { 2506 supportNew[0] = (cMax - cStart)*3 + (c - cMax)*4 + 1; 2507 supportNew[1] = (cMax - cStart)*3 + (c - cMax)*4 + 2; 2508 } 2509 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2510 #if defined(PETSC_USE_DEBUG) 2511 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2512 for (p = 0; p < 2; ++p) { 2513 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); 2514 } 2515 #endif 2516 } 2517 } 2518 /* Old vertices have identical supports */ 2519 for (v = vStart; v < vEnd; ++v) { 2520 const PetscInt newp = vStartNew + (v - vStart); 2521 const PetscInt *support, *cone; 2522 PetscInt size, s; 2523 2524 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2525 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2526 for (s = 0; s < size; ++s) { 2527 PetscInt r = 0; 2528 2529 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2530 if (cone[1] == v) r = 1; 2531 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2532 } 2533 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2534 #if defined(PETSC_USE_DEBUG) 2535 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2536 for (p = 0; p < size; ++p) { 2537 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); 2538 } 2539 #endif 2540 } 2541 /* Split-face vertices have cells + 2 supports */ 2542 for (f = fStart; f < fEnd; ++f) { 2543 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2544 const PetscInt *cone, *support; 2545 PetscInt size, s; 2546 2547 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2548 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2549 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2550 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2551 for (s = 0; s < size; ++s) { 2552 PetscInt r = 0, coneSize; 2553 2554 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2555 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2556 if (coneSize == 3) { 2557 if (cone[1] == f) r = 1; 2558 else if (cone[2] == f) r = 2; 2559 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*3 + r; 2560 } else if (coneSize == 4) { 2561 if (cone[1] == f) r = 1; 2562 else if (cone[2] == f) r = 2; 2563 else if (cone[3] == f) r = 3; 2564 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (support[s] - cMax)*4 + r; 2565 } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected cone size %D", coneSize); 2566 } 2567 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2568 #if defined(PETSC_USE_DEBUG) 2569 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2570 for (p = 0; p < 2+size; ++p) { 2571 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); 2572 } 2573 #endif 2574 } 2575 /* Interior vertices have 3 supports */ 2576 for (c = cStart; c < cMax; ++c) { 2577 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2578 2579 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 0; 2580 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 1; 2581 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*3 + 2; 2582 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2583 } 2584 /* Hybrid interior vertices have 4 supports */ 2585 for (c = cMax; c < cEnd; ++c) { 2586 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + c - cStart; 2587 2588 supportRef[0] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 0; 2589 supportRef[1] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 1; 2590 supportRef[2] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 2; 2591 supportRef[3] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (c - cMax)*4 + 3; 2592 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2593 } 2594 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2595 break; 2596 case REFINER_HEX_2D: 2597 /* 2598 3---------2---------2 2599 | | | 2600 | D 2 C | 2601 | | | 2602 3----3----0----1----1 2603 | | | 2604 | A 0 B | 2605 | | | 2606 0---------0---------1 2607 */ 2608 /* All cells have 4 faces */ 2609 for (c = cStart; c < cEnd; ++c) { 2610 const PetscInt newp = (c - cStart)*4; 2611 const PetscInt *cone, *ornt; 2612 PetscInt coneNew[4], orntNew[4]; 2613 2614 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2615 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2616 /* A quad */ 2617 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2618 orntNew[0] = ornt[0]; 2619 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2620 orntNew[1] = 0; 2621 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2622 orntNew[2] = -2; 2623 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 2624 orntNew[3] = ornt[3]; 2625 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2626 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2627 #if defined(PETSC_USE_DEBUG) 2628 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); 2629 for (p = 0; p < 4; ++p) { 2630 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); 2631 } 2632 #endif 2633 /* B quad */ 2634 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2635 orntNew[0] = ornt[0]; 2636 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2637 orntNew[1] = ornt[1]; 2638 coneNew[2] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2639 orntNew[2] = -2; 2640 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 0; 2641 orntNew[3] = -2; 2642 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2643 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2644 #if defined(PETSC_USE_DEBUG) 2645 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); 2646 for (p = 0; p < 4; ++p) { 2647 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); 2648 } 2649 #endif 2650 /* C quad */ 2651 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 1; 2652 orntNew[0] = 0; 2653 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2654 orntNew[1] = ornt[1]; 2655 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2656 orntNew[2] = ornt[2]; 2657 coneNew[3] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2658 orntNew[3] = -2; 2659 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2660 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2661 #if defined(PETSC_USE_DEBUG) 2662 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); 2663 for (p = 0; p < 4; ++p) { 2664 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); 2665 } 2666 #endif 2667 /* D quad */ 2668 coneNew[0] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 3; 2669 orntNew[0] = 0; 2670 coneNew[1] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + 2; 2671 orntNew[1] = 0; 2672 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2673 orntNew[2] = ornt[2]; 2674 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 2675 orntNew[3] = ornt[3]; 2676 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2677 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2678 #if defined(PETSC_USE_DEBUG) 2679 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); 2680 for (p = 0; p < 4; ++p) { 2681 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); 2682 } 2683 #endif 2684 } 2685 /* Split faces have 2 vertices and the same cells as the parent */ 2686 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2687 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2688 for (f = fStart; f < fEnd; ++f) { 2689 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2690 2691 for (r = 0; r < 2; ++r) { 2692 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2693 const PetscInt *cone, *ornt, *support; 2694 PetscInt coneNew[2], coneSize, c, supportSize, s; 2695 2696 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2697 coneNew[0] = vStartNew + (cone[0] - vStart); 2698 coneNew[1] = vStartNew + (cone[1] - vStart); 2699 coneNew[(r+1)%2] = newv; 2700 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2701 #if defined(PETSC_USE_DEBUG) 2702 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2703 for (p = 0; p < 2; ++p) { 2704 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); 2705 } 2706 #endif 2707 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2708 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2709 for (s = 0; s < supportSize; ++s) { 2710 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2711 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2712 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2713 for (c = 0; c < coneSize; ++c) { 2714 if (cone[c] == f) break; 2715 } 2716 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 2717 } 2718 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2719 #if defined(PETSC_USE_DEBUG) 2720 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2721 for (p = 0; p < supportSize; ++p) { 2722 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); 2723 } 2724 #endif 2725 } 2726 } 2727 /* Interior faces have 2 vertices and 2 cells */ 2728 for (c = cStart; c < cEnd; ++c) { 2729 const PetscInt *cone; 2730 PetscInt coneNew[2], supportNew[2]; 2731 2732 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2733 for (r = 0; r < 4; ++r) { 2734 const PetscInt newp = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2735 2736 if (r==1 || r==2) { 2737 coneNew[0] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2738 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2739 } else { 2740 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 2741 coneNew[1] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2742 } 2743 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2744 #if defined(PETSC_USE_DEBUG) 2745 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2746 for (p = 0; p < 2; ++p) { 2747 if ((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); 2748 } 2749 #endif 2750 supportNew[0] = (c - cStart)*4 + r; 2751 supportNew[1] = (c - cStart)*4 + (r+1)%4; 2752 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2753 #if defined(PETSC_USE_DEBUG) 2754 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2755 for (p = 0; p < 2; ++p) { 2756 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); 2757 } 2758 #endif 2759 } 2760 } 2761 /* Old vertices have identical supports */ 2762 for (v = vStart; v < vEnd; ++v) { 2763 const PetscInt newp = vStartNew + (v - vStart); 2764 const PetscInt *support, *cone; 2765 PetscInt size, s; 2766 2767 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 2768 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 2769 for (s = 0; s < size; ++s) { 2770 PetscInt r = 0; 2771 2772 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2773 if (cone[1] == v) r = 1; 2774 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 2775 } 2776 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2777 #if defined(PETSC_USE_DEBUG) 2778 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2779 for (p = 0; p < size; ++p) { 2780 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); 2781 } 2782 #endif 2783 } 2784 /* Face vertices have 2 + cells supports */ 2785 for (f = fStart; f < fEnd; ++f) { 2786 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 2787 const PetscInt *cone, *support; 2788 PetscInt size, s; 2789 2790 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 2791 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2792 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 2793 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 2794 for (s = 0; s < size; ++s) { 2795 PetscInt r = 0; 2796 2797 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2798 if (cone[1] == f) r = 1; 2799 else if (cone[2] == f) r = 2; 2800 else if (cone[3] == f) r = 3; 2801 supportRef[2+s] = fStartNew + (fEnd - fStart)*2 + (support[s] - cStart)*4 + r; 2802 } 2803 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2804 #if defined(PETSC_USE_DEBUG) 2805 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 2806 for (p = 0; p < 2+size; ++p) { 2807 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); 2808 } 2809 #endif 2810 } 2811 /* Cell vertices have 4 supports */ 2812 for (c = cStart; c < cEnd; ++c) { 2813 const PetscInt newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (c - cStart); 2814 PetscInt supportNew[4]; 2815 2816 for (r = 0; r < 4; ++r) { 2817 supportNew[r] = fStartNew + (fEnd - fStart)*2 + (c - cStart)*4 + r; 2818 } 2819 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 2820 } 2821 ierr = PetscFree(supportRef);CHKERRQ(ierr); 2822 break; 2823 case REFINER_HYBRID_SIMPLEX_2D: 2824 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 2825 cMax = PetscMin(cEnd, cMax); 2826 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 2827 fMax = PetscMin(fEnd, fMax); 2828 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 2829 /* Interior cells have 3 faces */ 2830 for (c = cStart; c < cMax; ++c) { 2831 const PetscInt newp = cStartNew + (c - cStart)*4; 2832 const PetscInt *cone, *ornt; 2833 PetscInt coneNew[3], orntNew[3]; 2834 2835 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2836 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2837 /* A triangle */ 2838 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 2839 orntNew[0] = ornt[0]; 2840 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2841 orntNew[1] = -2; 2842 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 2843 orntNew[2] = ornt[2]; 2844 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2845 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2846 #if defined(PETSC_USE_DEBUG) 2847 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); 2848 for (p = 0; p < 3; ++p) { 2849 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); 2850 } 2851 #endif 2852 /* B triangle */ 2853 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 2854 orntNew[0] = ornt[0]; 2855 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 2856 orntNew[1] = ornt[1]; 2857 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2858 orntNew[2] = -2; 2859 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2860 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2861 #if defined(PETSC_USE_DEBUG) 2862 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); 2863 for (p = 0; p < 3; ++p) { 2864 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); 2865 } 2866 #endif 2867 /* C triangle */ 2868 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2869 orntNew[0] = -2; 2870 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 2871 orntNew[1] = ornt[1]; 2872 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 2873 orntNew[2] = ornt[2]; 2874 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 2875 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 2876 #if defined(PETSC_USE_DEBUG) 2877 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); 2878 for (p = 0; p < 3; ++p) { 2879 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); 2880 } 2881 #endif 2882 /* D triangle */ 2883 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 0; 2884 orntNew[0] = 0; 2885 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 1; 2886 orntNew[1] = 0; 2887 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + 2; 2888 orntNew[2] = 0; 2889 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 2890 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 2891 #if defined(PETSC_USE_DEBUG) 2892 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); 2893 for (p = 0; p < 3; ++p) { 2894 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); 2895 } 2896 #endif 2897 } 2898 /* 2899 2----3----3 2900 | | 2901 | B | 2902 | | 2903 0----4--- 1 2904 | | 2905 | A | 2906 | | 2907 0----2----1 2908 */ 2909 /* Hybrid cells have 4 faces */ 2910 for (c = cMax; c < cEnd; ++c) { 2911 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 2912 const PetscInt *cone, *ornt; 2913 PetscInt coneNew[4], orntNew[4], r; 2914 2915 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 2916 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 2917 r = (ornt[0] < 0 ? 1 : 0); 2918 /* A quad */ 2919 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + r; 2920 orntNew[0] = ornt[0]; 2921 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + r; 2922 orntNew[1] = ornt[1]; 2923 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[2+r] - fMax); 2924 orntNew[2+r] = 0; 2925 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2926 orntNew[3-r] = 0; 2927 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 2928 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 2929 #if defined(PETSC_USE_DEBUG) 2930 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); 2931 for (p = 0; p < 4; ++p) { 2932 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); 2933 } 2934 #endif 2935 /* B quad */ 2936 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + 1-r; 2937 orntNew[0] = ornt[0]; 2938 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + 1-r; 2939 orntNew[1] = ornt[1]; 2940 coneNew[2+r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 2941 orntNew[2+r] = 0; 2942 coneNew[3-r] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (cone[3-r] - fMax); 2943 orntNew[3-r] = 0; 2944 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 2945 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 2946 #if defined(PETSC_USE_DEBUG) 2947 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); 2948 for (p = 0; p < 4; ++p) { 2949 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); 2950 } 2951 #endif 2952 } 2953 /* Interior split faces have 2 vertices and the same cells as the parent */ 2954 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 2955 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 2956 for (f = fStart; f < fMax; ++f) { 2957 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 2958 2959 for (r = 0; r < 2; ++r) { 2960 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 2961 const PetscInt *cone, *ornt, *support; 2962 PetscInt coneNew[2], coneSize, c, supportSize, s; 2963 2964 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 2965 coneNew[0] = vStartNew + (cone[0] - vStart); 2966 coneNew[1] = vStartNew + (cone[1] - vStart); 2967 coneNew[(r+1)%2] = newv; 2968 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 2969 #if defined(PETSC_USE_DEBUG) 2970 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2971 for (p = 0; p < 2; ++p) { 2972 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); 2973 } 2974 #endif 2975 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 2976 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 2977 for (s = 0; s < supportSize; ++s) { 2978 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 2979 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 2980 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 2981 for (c = 0; c < coneSize; ++c) if (cone[c] == f) break; 2982 if (support[s] >= cMax) { 2983 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[c] < 0 ? 1-r : r); 2984 } else { 2985 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%3 : (c+r)%3); 2986 } 2987 } 2988 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 2989 #if defined(PETSC_USE_DEBUG) 2990 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 2991 for (p = 0; p < supportSize; ++p) { 2992 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); 2993 } 2994 #endif 2995 } 2996 } 2997 /* Interior cell faces have 2 vertices and 2 cells */ 2998 for (c = cStart; c < cMax; ++c) { 2999 const PetscInt *cone; 3000 3001 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3002 for (r = 0; r < 3; ++r) { 3003 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*3 + r; 3004 PetscInt coneNew[2]; 3005 PetscInt supportNew[2]; 3006 3007 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3008 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - fStart); 3009 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3010 #if defined(PETSC_USE_DEBUG) 3011 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3012 for (p = 0; p < 2; ++p) { 3013 if ((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); 3014 } 3015 #endif 3016 supportNew[0] = (c - cStart)*4 + (r+1)%3; 3017 supportNew[1] = (c - cStart)*4 + 3; 3018 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3019 #if defined(PETSC_USE_DEBUG) 3020 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3021 for (p = 0; p < 2; ++p) { 3022 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); 3023 } 3024 #endif 3025 } 3026 } 3027 /* Interior hybrid faces have 2 vertices and the same cells */ 3028 for (f = fMax; f < fEnd; ++f) { 3029 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (f - fMax); 3030 const PetscInt *cone, *ornt; 3031 const PetscInt *support; 3032 PetscInt coneNew[2]; 3033 PetscInt supportNew[2]; 3034 PetscInt size, s, r; 3035 3036 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3037 coneNew[0] = vStartNew + (cone[0] - vStart); 3038 coneNew[1] = vStartNew + (cone[1] - vStart); 3039 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3040 #if defined(PETSC_USE_DEBUG) 3041 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3042 for (p = 0; p < 2; ++p) { 3043 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); 3044 } 3045 #endif 3046 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3047 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3048 for (s = 0; s < size; ++s) { 3049 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3050 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3051 for (r = 0; r < 2; ++r) { 3052 if (cone[r+2] == f) break; 3053 } 3054 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + (ornt[0] < 0 ? 1-r : r); 3055 } 3056 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3057 #if defined(PETSC_USE_DEBUG) 3058 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3059 for (p = 0; p < size; ++p) { 3060 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); 3061 } 3062 #endif 3063 } 3064 /* Cell hybrid faces have 2 vertices and 2 cells */ 3065 for (c = cMax; c < cEnd; ++c) { 3066 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (c - cMax); 3067 const PetscInt *cone; 3068 PetscInt coneNew[2]; 3069 PetscInt supportNew[2]; 3070 3071 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3072 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3073 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3074 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3075 #if defined(PETSC_USE_DEBUG) 3076 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3077 for (p = 0; p < 2; ++p) { 3078 if ((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); 3079 } 3080 #endif 3081 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3082 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3083 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3084 #if defined(PETSC_USE_DEBUG) 3085 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3086 for (p = 0; p < 2; ++p) { 3087 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 3088 } 3089 #endif 3090 } 3091 /* Old vertices have identical supports */ 3092 for (v = vStart; v < vEnd; ++v) { 3093 const PetscInt newp = vStartNew + (v - vStart); 3094 const PetscInt *support, *cone; 3095 PetscInt size, s; 3096 3097 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3098 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3099 for (s = 0; s < size; ++s) { 3100 if (support[s] >= fMax) { 3101 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (support[s] - fMax); 3102 } else { 3103 PetscInt r = 0; 3104 3105 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3106 if (cone[1] == v) r = 1; 3107 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3108 } 3109 } 3110 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3111 #if defined(PETSC_USE_DEBUG) 3112 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3113 for (p = 0; p < size; ++p) { 3114 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); 3115 } 3116 #endif 3117 } 3118 /* Face vertices have 2 + (2 interior, 1 hybrid) supports */ 3119 for (f = fStart; f < fMax; ++f) { 3120 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3121 const PetscInt *cone, *support; 3122 PetscInt size, newSize = 2, s; 3123 3124 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3125 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3126 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3127 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3128 for (s = 0; s < size; ++s) { 3129 PetscInt r = 0; 3130 3131 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3132 if (support[s] >= cMax) { 3133 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (fEnd - fMax) + (support[s] - cMax); 3134 3135 newSize += 1; 3136 } else { 3137 if (cone[1] == f) r = 1; 3138 else if (cone[2] == f) r = 2; 3139 supportRef[newSize+0] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + (r+2)%3; 3140 supportRef[newSize+1] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*3 + r; 3141 3142 newSize += 2; 3143 } 3144 } 3145 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3146 #if defined(PETSC_USE_DEBUG) 3147 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3148 for (p = 0; p < newSize; ++p) { 3149 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); 3150 } 3151 #endif 3152 } 3153 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3154 break; 3155 case REFINER_HYBRID_HEX_2D: 3156 /* Hybrid Hex 2D */ 3157 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 3158 cMax = PetscMin(cEnd, cMax); 3159 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 3160 fMax = PetscMin(fEnd, fMax); 3161 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, NULL, NULL);CHKERRQ(ierr); 3162 /* Interior cells have 4 faces */ 3163 for (c = cStart; c < cMax; ++c) { 3164 const PetscInt newp = cStartNew + (c - cStart)*4; 3165 const PetscInt *cone, *ornt; 3166 PetscInt coneNew[4], orntNew[4]; 3167 3168 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3169 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3170 /* A quad */ 3171 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3172 orntNew[0] = ornt[0]; 3173 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3174 orntNew[1] = 0; 3175 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3176 orntNew[2] = -2; 3177 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 0 : 1); 3178 orntNew[3] = ornt[3]; 3179 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3180 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3181 #if defined(PETSC_USE_DEBUG) 3182 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); 3183 for (p = 0; p < 4; ++p) { 3184 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); 3185 } 3186 #endif 3187 /* B quad */ 3188 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3189 orntNew[0] = ornt[0]; 3190 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3191 orntNew[1] = ornt[1]; 3192 coneNew[2] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3193 orntNew[2] = 0; 3194 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 0; 3195 orntNew[3] = -2; 3196 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3197 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3198 #if defined(PETSC_USE_DEBUG) 3199 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); 3200 for (p = 0; p < 4; ++p) { 3201 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); 3202 } 3203 #endif 3204 /* C quad */ 3205 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 1; 3206 orntNew[0] = -2; 3207 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3208 orntNew[1] = ornt[1]; 3209 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 1 : 0); 3210 orntNew[2] = ornt[2]; 3211 coneNew[3] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3212 orntNew[3] = 0; 3213 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3214 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3215 #if defined(PETSC_USE_DEBUG) 3216 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); 3217 for (p = 0; p < 4; ++p) { 3218 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); 3219 } 3220 #endif 3221 /* D quad */ 3222 coneNew[0] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 3; 3223 orntNew[0] = 0; 3224 coneNew[1] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + 2; 3225 orntNew[1] = -2; 3226 coneNew[2] = fStartNew + (cone[2] - fStart)*2 + (ornt[2] < 0 ? 0 : 1); 3227 orntNew[2] = ornt[2]; 3228 coneNew[3] = fStartNew + (cone[3] - fStart)*2 + (ornt[3] < 0 ? 1 : 0); 3229 orntNew[3] = ornt[3]; 3230 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3231 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3232 #if defined(PETSC_USE_DEBUG) 3233 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); 3234 for (p = 0; p < 4; ++p) { 3235 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); 3236 } 3237 #endif 3238 } 3239 /* 3240 2----3----3 3241 | | 3242 | B | 3243 | | 3244 0----4--- 1 3245 | | 3246 | A | 3247 | | 3248 0----2----1 3249 */ 3250 /* Hybrid cells have 4 faces */ 3251 for (c = cMax; c < cEnd; ++c) { 3252 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*2; 3253 const PetscInt *cone, *ornt; 3254 PetscInt coneNew[4], orntNew[4]; 3255 3256 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3257 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3258 /* A quad */ 3259 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 1 : 0); 3260 orntNew[0] = ornt[0]; 3261 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 1 : 0); 3262 orntNew[1] = ornt[1]; 3263 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[2] - fMax); 3264 orntNew[2] = 0; 3265 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3266 orntNew[3] = 0; 3267 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3268 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3269 #if defined(PETSC_USE_DEBUG) 3270 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); 3271 for (p = 0; p < 4; ++p) { 3272 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); 3273 } 3274 #endif 3275 /* B quad */ 3276 coneNew[0] = fStartNew + (cone[0] - fStart)*2 + (ornt[0] < 0 ? 0 : 1); 3277 orntNew[0] = ornt[0]; 3278 coneNew[1] = fStartNew + (cone[1] - fStart)*2 + (ornt[1] < 0 ? 0 : 1); 3279 orntNew[1] = ornt[1]; 3280 coneNew[2] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3281 orntNew[2] = 0; 3282 coneNew[3] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (cone[3] - fMax); 3283 orntNew[3] = 0; 3284 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3285 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3286 #if defined(PETSC_USE_DEBUG) 3287 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); 3288 for (p = 0; p < 4; ++p) { 3289 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); 3290 } 3291 #endif 3292 } 3293 /* Interior split faces have 2 vertices and the same cells as the parent */ 3294 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3295 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 3296 for (f = fStart; f < fMax; ++f) { 3297 const PetscInt newv = vStartNew + (vEnd - vStart) + (f - fStart); 3298 3299 for (r = 0; r < 2; ++r) { 3300 const PetscInt newp = fStartNew + (f - fStart)*2 + r; 3301 const PetscInt *cone, *ornt, *support; 3302 PetscInt coneNew[2], coneSize, c, supportSize, s; 3303 3304 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3305 coneNew[0] = vStartNew + (cone[0] - vStart); 3306 coneNew[1] = vStartNew + (cone[1] - vStart); 3307 coneNew[(r+1)%2] = newv; 3308 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3309 #if defined(PETSC_USE_DEBUG) 3310 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3311 for (p = 0; p < 2; ++p) { 3312 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); 3313 } 3314 #endif 3315 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3316 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3317 for (s = 0; s < supportSize; ++s) { 3318 if (support[s] >= cMax) { 3319 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3320 } else { 3321 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3322 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3323 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3324 for (c = 0; c < coneSize; ++c) { 3325 if (cone[c] == f) break; 3326 } 3327 supportRef[s] = cStartNew + (support[s] - cStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 3328 } 3329 } 3330 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3331 #if defined(PETSC_USE_DEBUG) 3332 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3333 for (p = 0; p < supportSize; ++p) { 3334 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); 3335 } 3336 #endif 3337 } 3338 } 3339 /* Interior cell faces have 2 vertices and 2 cells */ 3340 for (c = cStart; c < cMax; ++c) { 3341 const PetscInt *cone; 3342 3343 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3344 for (r = 0; r < 4; ++r) { 3345 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3346 PetscInt coneNew[2], supportNew[2]; 3347 3348 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - fStart); 3349 coneNew[1] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3350 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3351 #if defined(PETSC_USE_DEBUG) 3352 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3353 for (p = 0; p < 2; ++p) { 3354 if ((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); 3355 } 3356 #endif 3357 supportNew[0] = (c - cStart)*4 + r; 3358 supportNew[1] = (c - cStart)*4 + (r+1)%4; 3359 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3360 #if defined(PETSC_USE_DEBUG) 3361 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3362 for (p = 0; p < 2; ++p) { 3363 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); 3364 } 3365 #endif 3366 } 3367 } 3368 /* Hybrid faces have 2 vertices and the same cells */ 3369 for (f = fMax; f < fEnd; ++f) { 3370 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (f - fMax); 3371 const PetscInt *cone, *support; 3372 PetscInt coneNew[2], supportNew[2]; 3373 PetscInt size, s, r; 3374 3375 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3376 coneNew[0] = vStartNew + (cone[0] - vStart); 3377 coneNew[1] = vStartNew + (cone[1] - vStart); 3378 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3379 #if defined(PETSC_USE_DEBUG) 3380 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3381 for (p = 0; p < 2; ++p) { 3382 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); 3383 } 3384 #endif 3385 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3386 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3387 for (s = 0; s < size; ++s) { 3388 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3389 for (r = 0; r < 2; ++r) { 3390 if (cone[r+2] == f) break; 3391 } 3392 supportNew[s] = (cMax - cStart)*4 + (support[s] - cMax)*2 + r; 3393 } 3394 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3395 #if defined(PETSC_USE_DEBUG) 3396 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3397 for (p = 0; p < size; ++p) { 3398 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); 3399 } 3400 #endif 3401 } 3402 /* Cell hybrid faces have 2 vertices and 2 cells */ 3403 for (c = cMax; c < cEnd; ++c) { 3404 const PetscInt newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (c - cMax); 3405 const PetscInt *cone; 3406 PetscInt coneNew[2], supportNew[2]; 3407 3408 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3409 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - fStart); 3410 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - fStart); 3411 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3412 #if defined(PETSC_USE_DEBUG) 3413 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3414 for (p = 0; p < 2; ++p) { 3415 if ((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); 3416 } 3417 #endif 3418 supportNew[0] = (cMax - cStart)*4 + (c - cMax)*2 + 0; 3419 supportNew[1] = (cMax - cStart)*4 + (c - cMax)*2 + 1; 3420 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3421 #if defined(PETSC_USE_DEBUG) 3422 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3423 for (p = 0; p < 2; ++p) { 3424 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); 3425 } 3426 #endif 3427 } 3428 /* Old vertices have identical supports */ 3429 for (v = vStart; v < vEnd; ++v) { 3430 const PetscInt newp = vStartNew + (v - vStart); 3431 const PetscInt *support, *cone; 3432 PetscInt size, s; 3433 3434 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 3435 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 3436 for (s = 0; s < size; ++s) { 3437 if (support[s] >= fMax) { 3438 supportRef[s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (support[s] - fMax); 3439 } else { 3440 PetscInt r = 0; 3441 3442 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3443 if (cone[1] == v) r = 1; 3444 supportRef[s] = fStartNew + (support[s] - fStart)*2 + r; 3445 } 3446 } 3447 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3448 #if defined(PETSC_USE_DEBUG) 3449 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3450 for (p = 0; p < size; ++p) { 3451 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); 3452 } 3453 #endif 3454 } 3455 /* Face vertices have 2 + cells supports */ 3456 for (f = fStart; f < fMax; ++f) { 3457 const PetscInt newp = vStartNew + (vEnd - vStart) + (f - fStart); 3458 const PetscInt *cone, *support; 3459 PetscInt size, s; 3460 3461 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 3462 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3463 supportRef[0] = fStartNew + (f - fStart)*2 + 0; 3464 supportRef[1] = fStartNew + (f - fStart)*2 + 1; 3465 for (s = 0; s < size; ++s) { 3466 PetscInt r = 0; 3467 3468 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3469 if (support[s] >= cMax) { 3470 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (fEnd - fMax) + (support[s] - cMax); 3471 } else { 3472 if (cone[1] == f) r = 1; 3473 else if (cone[2] == f) r = 2; 3474 else if (cone[3] == f) r = 3; 3475 supportRef[2+s] = fStartNew + (fMax - fStart)*2 + (support[s] - cStart)*4 + r; 3476 } 3477 } 3478 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3479 #if defined(PETSC_USE_DEBUG) 3480 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 3481 for (p = 0; p < 2+size; ++p) { 3482 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); 3483 } 3484 #endif 3485 } 3486 /* Cell vertices have 4 supports */ 3487 for (c = cStart; c < cMax; ++c) { 3488 const PetscInt newp = vStartNew + (vEnd - vStart) + (fMax - fStart) + (c - cStart); 3489 PetscInt supportNew[4]; 3490 3491 for (r = 0; r < 4; ++r) { 3492 supportNew[r] = fStartNew + (fMax - fStart)*2 + (c - cStart)*4 + r; 3493 } 3494 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3495 } 3496 ierr = PetscFree(supportRef);CHKERRQ(ierr); 3497 break; 3498 case REFINER_SIMPLEX_3D: 3499 /* All cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 3500 ierr = DMPlexGetRawFaces_Internal(dm, DM_POLYTOPE_TETRAHEDRON, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 3501 for (c = cStart; c < cEnd; ++c) { 3502 const PetscInt newp = cStartNew + (c - cStart)*8; 3503 const PetscInt *cone, *ornt; 3504 PetscInt coneNew[4], orntNew[4]; 3505 3506 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3507 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3508 /* A tetrahedron: {0, a, c, d} */ 3509 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 3510 orntNew[0] = ornt[0]; 3511 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 3512 orntNew[1] = ornt[1]; 3513 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 3514 orntNew[2] = ornt[2]; 3515 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3516 orntNew[3] = 0; 3517 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3518 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3519 #if defined(PETSC_USE_DEBUG) 3520 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); 3521 for (p = 0; p < 4; ++p) { 3522 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); 3523 } 3524 #endif 3525 /* B tetrahedron: {a, 1, b, e} */ 3526 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 3527 orntNew[0] = ornt[0]; 3528 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 3529 orntNew[1] = ornt[1]; 3530 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3531 orntNew[2] = 0; 3532 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 3533 orntNew[3] = ornt[3]; 3534 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3535 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3536 #if defined(PETSC_USE_DEBUG) 3537 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); 3538 for (p = 0; p < 4; ++p) { 3539 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); 3540 } 3541 #endif 3542 /* C tetrahedron: {c, b, 2, f} */ 3543 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 3544 orntNew[0] = ornt[0]; 3545 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3546 orntNew[1] = 0; 3547 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 3548 orntNew[2] = ornt[2]; 3549 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 3550 orntNew[3] = ornt[3]; 3551 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3552 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3553 #if defined(PETSC_USE_DEBUG) 3554 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); 3555 for (p = 0; p < 4; ++p) { 3556 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); 3557 } 3558 #endif 3559 /* D tetrahedron: {d, e, f, 3} */ 3560 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3561 orntNew[0] = 0; 3562 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 3563 orntNew[1] = ornt[1]; 3564 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 3565 orntNew[2] = ornt[2]; 3566 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 3567 orntNew[3] = ornt[3]; 3568 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3569 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3570 #if defined(PETSC_USE_DEBUG) 3571 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); 3572 for (p = 0; p < 4; ++p) { 3573 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); 3574 } 3575 #endif 3576 /* A' tetrahedron: {c, d, a, f} */ 3577 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 0; 3578 orntNew[0] = -3; 3579 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 3580 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 3581 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3582 orntNew[2] = 0; 3583 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3584 orntNew[3] = 2; 3585 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 3586 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 3587 #if defined(PETSC_USE_DEBUG) 3588 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); 3589 for (p = 0; p < 4; ++p) { 3590 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); 3591 } 3592 #endif 3593 /* B' tetrahedron: {e, b, a, f} */ 3594 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 1; 3595 orntNew[0] = -2; 3596 coneNew[1] = fStartNew + (cone[3] - fStart)*4 + 3; 3597 orntNew[1] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 1)+1) : GetTriMidEdge_Static(ornt[3], 1); 3598 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3599 orntNew[2] = 0; 3600 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3601 orntNew[3] = 0; 3602 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 3603 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 3604 #if defined(PETSC_USE_DEBUG) 3605 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); 3606 for (p = 0; p < 4; ++p) { 3607 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); 3608 } 3609 #endif 3610 /* C' tetrahedron: {f, a, c, b} */ 3611 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 3612 orntNew[0] = -2; 3613 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 3614 orntNew[1] = -2; 3615 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 2; 3616 orntNew[2] = -1; 3617 coneNew[3] = fStartNew + (cone[0] - fStart)*4 + 3; 3618 orntNew[3] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 3619 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 3620 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 3621 #if defined(PETSC_USE_DEBUG) 3622 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); 3623 for (p = 0; p < 4; ++p) { 3624 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); 3625 } 3626 #endif 3627 /* D' tetrahedron: {f, a, e, d} */ 3628 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 3629 orntNew[0] = -2; 3630 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 3631 orntNew[1] = -1; 3632 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 3; 3633 orntNew[2] = -2; 3634 coneNew[3] = fStartNew + (cone[1] - fStart)*4 + 3; 3635 orntNew[3] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 1)+1) : GetTriMidEdge_Static(ornt[1], 1); 3636 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 3637 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 3638 #if defined(PETSC_USE_DEBUG) 3639 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); 3640 for (p = 0; p < 4; ++p) { 3641 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); 3642 } 3643 #endif 3644 } 3645 /* Split faces have 3 edges and the same cells as the parent */ 3646 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 3647 ierr = PetscMalloc1(2 + maxSupportSize*3, &supportRef);CHKERRQ(ierr); 3648 for (f = fStart; f < fEnd; ++f) { 3649 const PetscInt newp = fStartNew + (f - fStart)*4; 3650 const PetscInt *cone, *ornt, *support; 3651 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 3652 3653 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 3654 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 3655 /* A triangle */ 3656 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 3657 orntNew[0] = ornt[0]; 3658 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3659 orntNew[1] = -2; 3660 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 3661 orntNew[2] = ornt[2]; 3662 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 3663 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 3664 #if defined(PETSC_USE_DEBUG) 3665 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); 3666 for (p = 0; p < 3; ++p) { 3667 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); 3668 } 3669 #endif 3670 /* B triangle */ 3671 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 3672 orntNew[0] = ornt[0]; 3673 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 3674 orntNew[1] = ornt[1]; 3675 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3676 orntNew[2] = -2; 3677 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 3678 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 3679 #if defined(PETSC_USE_DEBUG) 3680 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); 3681 for (p = 0; p < 3; ++p) { 3682 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); 3683 } 3684 #endif 3685 /* C triangle */ 3686 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3687 orntNew[0] = -2; 3688 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 3689 orntNew[1] = ornt[1]; 3690 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 3691 orntNew[2] = ornt[2]; 3692 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 3693 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 3694 #if defined(PETSC_USE_DEBUG) 3695 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); 3696 for (p = 0; p < 3; ++p) { 3697 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); 3698 } 3699 #endif 3700 /* D triangle */ 3701 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 3702 orntNew[0] = 0; 3703 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 3704 orntNew[1] = 0; 3705 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 3706 orntNew[2] = 0; 3707 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 3708 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 3709 #if defined(PETSC_USE_DEBUG) 3710 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); 3711 for (p = 0; p < 3; ++p) { 3712 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); 3713 } 3714 #endif 3715 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3716 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3717 for (r = 0; r < 4; ++r) { 3718 for (s = 0; s < supportSize; ++s) { 3719 PetscInt subf; 3720 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3721 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3722 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3723 for (c = 0; c < coneSize; ++c) { 3724 if (cone[c] == f) break; 3725 } 3726 subf = GetTriSubfaceInverse_Static(ornt[c], r); 3727 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 3728 } 3729 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 3730 #if defined(PETSC_USE_DEBUG) 3731 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); 3732 for (p = 0; p < supportSize; ++p) { 3733 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); 3734 } 3735 #endif 3736 } 3737 } 3738 /* Interior faces have 3 edges and 2 cells */ 3739 for (c = cStart; c < cEnd; ++c) { 3740 PetscInt newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8; 3741 const PetscInt *cone, *ornt; 3742 PetscInt coneNew[3], orntNew[3]; 3743 PetscInt supportNew[2]; 3744 3745 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 3746 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 3747 /* Face A: {c, a, d} */ 3748 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3749 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3750 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3751 orntNew[1] = ornt[1] < 0 ? -2 : 0; 3752 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 3753 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3754 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3755 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3756 #if defined(PETSC_USE_DEBUG) 3757 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3758 for (p = 0; p < 3; ++p) { 3759 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); 3760 } 3761 #endif 3762 supportNew[0] = (c - cStart)*8 + 0; 3763 supportNew[1] = (c - cStart)*8 + 0+4; 3764 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3765 #if defined(PETSC_USE_DEBUG) 3766 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3767 for (p = 0; p < 2; ++p) { 3768 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); 3769 } 3770 #endif 3771 ++newp; 3772 /* Face B: {a, b, e} */ 3773 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3774 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3775 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 3776 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3777 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3778 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3779 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3780 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3781 #if defined(PETSC_USE_DEBUG) 3782 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3783 for (p = 0; p < 3; ++p) { 3784 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); 3785 } 3786 #endif 3787 supportNew[0] = (c - cStart)*8 + 1; 3788 supportNew[1] = (c - cStart)*8 + 1+4; 3789 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3790 #if defined(PETSC_USE_DEBUG) 3791 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3792 for (p = 0; p < 2; ++p) { 3793 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); 3794 } 3795 #endif 3796 ++newp; 3797 /* Face C: {c, f, b} */ 3798 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3799 orntNew[0] = ornt[2] < 0 ? -2 : 0; 3800 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3801 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3802 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 3803 orntNew[2] = ornt[0] < 0 ? -2 : 0; 3804 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3805 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3806 #if defined(PETSC_USE_DEBUG) 3807 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3808 for (p = 0; p < 3; ++p) { 3809 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); 3810 } 3811 #endif 3812 supportNew[0] = (c - cStart)*8 + 2; 3813 supportNew[1] = (c - cStart)*8 + 2+4; 3814 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3815 #if defined(PETSC_USE_DEBUG) 3816 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3817 for (p = 0; p < 2; ++p) { 3818 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); 3819 } 3820 #endif 3821 ++newp; 3822 /* Face D: {d, e, f} */ 3823 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 3824 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3825 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3826 orntNew[1] = ornt[3] < 0 ? -2 : 0; 3827 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3828 orntNew[2] = ornt[2] < 0 ? -2 : 0; 3829 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3830 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3831 #if defined(PETSC_USE_DEBUG) 3832 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3833 for (p = 0; p < 3; ++p) { 3834 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); 3835 } 3836 #endif 3837 supportNew[0] = (c - cStart)*8 + 3; 3838 supportNew[1] = (c - cStart)*8 + 3+4; 3839 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3840 #if defined(PETSC_USE_DEBUG) 3841 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3842 for (p = 0; p < 2; ++p) { 3843 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); 3844 } 3845 #endif 3846 ++newp; 3847 /* Face E: {d, f, a} */ 3848 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 3849 orntNew[0] = ornt[2] < 0 ? 0 : -2; 3850 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3851 orntNew[1] = -2; 3852 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 3853 orntNew[2] = ornt[1] < 0 ? -2 : 0; 3854 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3855 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3856 #if defined(PETSC_USE_DEBUG) 3857 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3858 for (p = 0; p < 3; ++p) { 3859 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); 3860 } 3861 #endif 3862 supportNew[0] = (c - cStart)*8 + 0+4; 3863 supportNew[1] = (c - cStart)*8 + 3+4; 3864 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3865 #if defined(PETSC_USE_DEBUG) 3866 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3867 for (p = 0; p < 2; ++p) { 3868 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); 3869 } 3870 #endif 3871 ++newp; 3872 /* Face F: {c, a, f} */ 3873 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 3874 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3875 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3876 orntNew[1] = 0; 3877 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 3878 orntNew[2] = ornt[2] < 0 ? 0 : -2; 3879 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3880 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3881 #if defined(PETSC_USE_DEBUG) 3882 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3883 for (p = 0; p < 3; ++p) { 3884 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); 3885 } 3886 #endif 3887 supportNew[0] = (c - cStart)*8 + 0+4; 3888 supportNew[1] = (c - cStart)*8 + 2+4; 3889 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3890 #if defined(PETSC_USE_DEBUG) 3891 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3892 for (p = 0; p < 2; ++p) { 3893 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); 3894 } 3895 #endif 3896 ++newp; 3897 /* Face G: {e, a, f} */ 3898 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 3899 orntNew[0] = ornt[1] < 0 ? -2 : 0; 3900 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3901 orntNew[1] = 0; 3902 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 3903 orntNew[2] = ornt[3] < 0 ? 0 : -2; 3904 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3905 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3906 #if defined(PETSC_USE_DEBUG) 3907 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3908 for (p = 0; p < 3; ++p) { 3909 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); 3910 } 3911 #endif 3912 supportNew[0] = (c - cStart)*8 + 1+4; 3913 supportNew[1] = (c - cStart)*8 + 3+4; 3914 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3915 #if defined(PETSC_USE_DEBUG) 3916 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3917 for (p = 0; p < 2; ++p) { 3918 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); 3919 } 3920 #endif 3921 ++newp; 3922 /* Face H: {a, b, f} */ 3923 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 3924 orntNew[0] = ornt[0] < 0 ? -2 : 0; 3925 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 3926 orntNew[1] = ornt[3] < 0 ? 0 : -2; 3927 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 3928 orntNew[2] = -2; 3929 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3930 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 3931 #if defined(PETSC_USE_DEBUG) 3932 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3933 for (p = 0; p < 3; ++p) { 3934 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); 3935 } 3936 #endif 3937 supportNew[0] = (c - cStart)*8 + 1+4; 3938 supportNew[1] = (c - cStart)*8 + 2+4; 3939 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 3940 #if defined(PETSC_USE_DEBUG) 3941 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 3942 for (p = 0; p < 2; ++p) { 3943 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); 3944 } 3945 #endif 3946 ++newp; 3947 } 3948 /* Split Edges have 2 vertices and the same faces as the parent */ 3949 for (e = eStart; e < eEnd; ++e) { 3950 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 3951 3952 for (r = 0; r < 2; ++r) { 3953 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 3954 const PetscInt *cone, *ornt, *support; 3955 PetscInt coneNew[2], coneSize, c, supportSize, s; 3956 3957 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 3958 coneNew[0] = vStartNew + (cone[0] - vStart); 3959 coneNew[1] = vStartNew + (cone[1] - vStart); 3960 coneNew[(r+1)%2] = newv; 3961 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 3962 #if defined(PETSC_USE_DEBUG) 3963 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3964 for (p = 0; p < 2; ++p) { 3965 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); 3966 } 3967 #endif 3968 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 3969 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 3970 for (s = 0; s < supportSize; ++s) { 3971 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 3972 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 3973 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 3974 for (c = 0; c < coneSize; ++c) { 3975 if (cone[c] == e) break; 3976 } 3977 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 3978 } 3979 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 3980 #if defined(PETSC_USE_DEBUG) 3981 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 3982 for (p = 0; p < supportSize; ++p) { 3983 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); 3984 } 3985 #endif 3986 } 3987 } 3988 /* Face edges have 2 vertices and 2+cells*(1/2) faces */ 3989 for (f = fStart; f < fEnd; ++f) { 3990 const PetscInt *cone, *ornt, *support; 3991 PetscInt coneSize, supportSize, s; 3992 3993 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 3994 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 3995 for (r = 0; r < 3; ++r) { 3996 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 3997 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 3998 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 3999 -1, -1, 1, 6, 0, 4, 4000 2, 5, 3, 4, -1, -1, 4001 -1, -1, 3, 6, 2, 7}; 4002 4003 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4004 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4005 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4006 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4007 #if defined(PETSC_USE_DEBUG) 4008 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4009 for (p = 0; p < 2; ++p) { 4010 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); 4011 } 4012 #endif 4013 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4014 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4015 for (s = 0; s < supportSize; ++s) { 4016 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4017 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4018 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4019 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4020 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4021 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4022 if (er == eint[c]) { 4023 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4024 } else { 4025 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4026 supportRef[2+intFaces++] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4027 } 4028 } 4029 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4030 #if defined(PETSC_USE_DEBUG) 4031 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4032 for (p = 0; p < intFaces; ++p) { 4033 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); 4034 } 4035 #endif 4036 } 4037 } 4038 /* Interior edges have 2 vertices and 4 faces */ 4039 for (c = cStart; c < cEnd; ++c) { 4040 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart); 4041 const PetscInt *cone, *ornt, *fcone; 4042 PetscInt coneNew[2], supportNew[4], find; 4043 4044 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4045 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4046 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4047 find = GetTriEdge_Static(ornt[0], 0); 4048 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4049 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4050 find = GetTriEdge_Static(ornt[2], 1); 4051 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4052 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4053 #if defined(PETSC_USE_DEBUG) 4054 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4055 for (p = 0; p < 2; ++p) { 4056 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); 4057 } 4058 #endif 4059 supportNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 4; 4060 supportNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 5; 4061 supportNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 6; 4062 supportNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*8 + 7; 4063 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4064 #if defined(PETSC_USE_DEBUG) 4065 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 4066 for (p = 0; p < 4; ++p) { 4067 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); 4068 } 4069 #endif 4070 } 4071 /* Old vertices have identical supports */ 4072 for (v = vStart; v < vEnd; ++v) { 4073 const PetscInt newp = vStartNew + (v - vStart); 4074 const PetscInt *support, *cone; 4075 PetscInt size, s; 4076 4077 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4078 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4079 for (s = 0; s < size; ++s) { 4080 PetscInt r = 0; 4081 4082 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4083 if (cone[1] == v) r = 1; 4084 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4085 } 4086 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4087 #if defined(PETSC_USE_DEBUG) 4088 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4089 for (p = 0; p < size; ++p) { 4090 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); 4091 } 4092 #endif 4093 } 4094 /* Edge vertices have 2 + face*2 + 0/1 supports */ 4095 for (e = eStart; e < eEnd; ++e) { 4096 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4097 const PetscInt *cone, *support; 4098 PetscInt *star = NULL, starSize, cellSize = 0, coneSize, size, s; 4099 4100 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4101 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4102 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4103 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4104 for (s = 0; s < size; ++s) { 4105 PetscInt r = 0; 4106 4107 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4108 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4109 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4110 supportRef[2+s*2+0] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4111 supportRef[2+s*2+1] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4112 } 4113 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4114 for (s = 0; s < starSize*2; s += 2) { 4115 const PetscInt *cone, *ornt; 4116 PetscInt e01, e23; 4117 4118 if ((star[s] >= cStart) && (star[s] < cEnd)) { 4119 /* Check edge 0-1 */ 4120 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4121 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4122 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 4123 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 4124 /* Check edge 2-3 */ 4125 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 4126 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 4127 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 4128 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 4129 if ((e01 == e) || (e23 == e)) {supportRef[2+size*2+cellSize++] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (star[s] - cStart);} 4130 } 4131 } 4132 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 4133 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4134 #if defined(PETSC_USE_DEBUG) 4135 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4136 for (p = 0; p < 2+size*2+cellSize; ++p) { 4137 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); 4138 } 4139 #endif 4140 } 4141 ierr = PetscFree(supportRef);CHKERRQ(ierr); 4142 ierr = DMPlexRestoreFaces_Internal(dm, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 4143 break; 4144 case REFINER_HYBRID_SIMPLEX_3D: 4145 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 4146 /* Interior cells have 4 faces: Tet face order is prescribed in DMPlexGetFaces_Internal() */ 4147 ierr = DMPlexGetRawFaces_Internal(dm, DM_POLYTOPE_TETRAHEDRON, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 4148 for (c = cStart; c < cMax; ++c) { 4149 const PetscInt newp = cStartNew + (c - cStart)*8; 4150 const PetscInt *cone, *ornt; 4151 PetscInt coneNew[4], orntNew[4]; 4152 4153 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4154 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4155 /* A tetrahedron: {0, a, c, d} */ 4156 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 0); /* A */ 4157 orntNew[0] = ornt[0]; 4158 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 0); /* A */ 4159 orntNew[1] = ornt[1]; 4160 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 0); /* A */ 4161 orntNew[2] = ornt[2]; 4162 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4163 orntNew[3] = 0; 4164 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4165 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4166 #if defined(PETSC_USE_DEBUG) 4167 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); 4168 for (p = 0; p < 4; ++p) { 4169 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); 4170 } 4171 #endif 4172 /* B tetrahedron: {a, 1, b, e} */ 4173 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 1); /* B */ 4174 orntNew[0] = ornt[0]; 4175 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 2); /* C */ 4176 orntNew[1] = ornt[1]; 4177 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4178 orntNew[2] = 0; 4179 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 1); /* B */ 4180 orntNew[3] = ornt[3]; 4181 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4182 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4183 #if defined(PETSC_USE_DEBUG) 4184 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); 4185 for (p = 0; p < 4; ++p) { 4186 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); 4187 } 4188 #endif 4189 /* C tetrahedron: {c, b, 2, f} */ 4190 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], 2); /* C */ 4191 orntNew[0] = ornt[0]; 4192 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4193 orntNew[1] = 0; 4194 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 1); /* B */ 4195 orntNew[2] = ornt[2]; 4196 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 0); /* A */ 4197 orntNew[3] = ornt[3]; 4198 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4199 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4200 #if defined(PETSC_USE_DEBUG) 4201 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); 4202 for (p = 0; p < 4; ++p) { 4203 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); 4204 } 4205 #endif 4206 /* D tetrahedron: {d, e, f, 3} */ 4207 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4208 orntNew[0] = 0; 4209 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], 1); /* B */ 4210 orntNew[1] = ornt[1]; 4211 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetTriSubface_Static(ornt[2], 2); /* C */ 4212 orntNew[2] = ornt[2]; 4213 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetTriSubface_Static(ornt[3], 2); /* C */ 4214 orntNew[3] = ornt[3]; 4215 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4216 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4217 #if defined(PETSC_USE_DEBUG) 4218 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); 4219 for (p = 0; p < 4; ++p) { 4220 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); 4221 } 4222 #endif 4223 /* A' tetrahedron: {d, a, c, f} */ 4224 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 0; 4225 orntNew[0] = -3; 4226 coneNew[1] = fStartNew + (cone[2] - fStart)*4 + 3; 4227 orntNew[1] = ornt[2] < 0 ? -(GetTriMidEdge_Static(ornt[2], 0)+1) : GetTriMidEdge_Static(ornt[2], 0); 4228 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4229 orntNew[2] = 0; 4230 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4231 orntNew[3] = 2; 4232 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 4233 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 4234 #if defined(PETSC_USE_DEBUG) 4235 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); 4236 for (p = 0; p < 4; ++p) { 4237 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); 4238 } 4239 #endif 4240 /* B' tetrahedron: {e, b, a, f} */ 4241 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 1; 4242 orntNew[0] = -3; 4243 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4244 orntNew[1] = 1; 4245 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4246 orntNew[2] = 0; 4247 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + 3; 4248 orntNew[3] = ornt[3] < 0 ? -(GetTriMidEdge_Static(ornt[3], 0)+1) : GetTriMidEdge_Static(ornt[3], 0); 4249 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 4250 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 4251 #if defined(PETSC_USE_DEBUG) 4252 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); 4253 for (p = 0; p < 4; ++p) { 4254 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); 4255 } 4256 #endif 4257 /* C' tetrahedron: {b, f, c, a} */ 4258 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 2; 4259 orntNew[0] = -3; 4260 coneNew[1] = fStartNew + (cone[0] - fStart)*4 + 3; 4261 orntNew[1] = ornt[0] < 0 ? -(GetTriMidEdge_Static(ornt[0], 2)+1) : GetTriMidEdge_Static(ornt[0], 2); 4262 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4263 orntNew[2] = -3; 4264 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4265 orntNew[3] = -2; 4266 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 4267 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 4268 #if defined(PETSC_USE_DEBUG) 4269 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); 4270 for (p = 0; p < 4; ++p) { 4271 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); 4272 } 4273 #endif 4274 /* D' tetrahedron: {f, e, d, a} */ 4275 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 3; 4276 orntNew[0] = -3; 4277 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4278 orntNew[1] = -3; 4279 coneNew[2] = fStartNew + (cone[1] - fStart)*4 + 3; 4280 orntNew[2] = ornt[1] < 0 ? -(GetTriMidEdge_Static(ornt[1], 0)+1) : GetTriMidEdge_Static(ornt[1], 0); 4281 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4282 orntNew[3] = -3; 4283 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 4284 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 4285 #if defined(PETSC_USE_DEBUG) 4286 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); 4287 for (p = 0; p < 4; ++p) { 4288 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); 4289 } 4290 #endif 4291 } 4292 /* Hybrid cells have 5 faces */ 4293 for (c = cMax; c < cEnd; ++c) { 4294 const PetscInt newp = cStartNew + (cMax - cStart)*8 + (c - cMax)*4; 4295 const PetscInt *cone, *ornt, *fornt; 4296 PetscInt coneNew[5], orntNew[5], o, of, i; 4297 4298 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4299 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4300 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 4301 o = ornt[0] < 0 ? -1 : 1; 4302 for (r = 0; r < 3; ++r) { 4303 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetTriSubface_Static(ornt[0], r); 4304 orntNew[0] = ornt[0]; 4305 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetTriSubface_Static(ornt[1], r); 4306 orntNew[1] = ornt[1]; 4307 of = fornt[GetTriEdge_Static(ornt[0], r)] < 0 ? -1 : 1; 4308 i = GetTriEdgeInverse_Static(ornt[0], r) + 2; 4309 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (cone[2+GetTriEdge_Static(ornt[0], r)] - fMax)*2 + (o*of < 0 ? 1 : 0); 4310 orntNew[i] = 0; 4311 i = GetTriEdgeInverse_Static(ornt[0], (r+1)%3) + 2; 4312 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + GetTriSubface_Static(ornt[0], r); 4313 orntNew[i] = 0; 4314 of = fornt[GetTriEdge_Static(ornt[0], (r+2)%3)] < 0 ? -1 : 1; 4315 i = GetTriEdgeInverse_Static(ornt[0], (r+2)%3) + 2; 4316 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); 4317 orntNew[i] = 0; 4318 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4319 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4320 #if defined(PETSC_USE_DEBUG) 4321 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); 4322 for (p = 0; p < 2; ++p) { 4323 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); 4324 } 4325 for (p = 2; p < 5; ++p) { 4326 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); 4327 } 4328 #endif 4329 } 4330 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + 3; 4331 orntNew[0] = 0; 4332 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + 3; 4333 orntNew[1] = 0; 4334 coneNew[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 4335 orntNew[2] = 0; 4336 coneNew[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 4337 orntNew[3] = 0; 4338 coneNew[4] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 4339 orntNew[4] = 0; 4340 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4341 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4342 #if defined(PETSC_USE_DEBUG) 4343 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); 4344 for (p = 0; p < 2; ++p) { 4345 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); 4346 } 4347 for (p = 2; p < 5; ++p) { 4348 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); 4349 } 4350 #endif 4351 } 4352 /* Split faces have 3 edges and the same cells as the parent */ 4353 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 4354 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 4355 for (f = fStart; f < fMax; ++f) { 4356 const PetscInt newp = fStartNew + (f - fStart)*4; 4357 const PetscInt *cone, *ornt, *support; 4358 PetscInt coneNew[3], orntNew[3], coneSize, supportSize, s; 4359 4360 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4361 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4362 /* A triangle */ 4363 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 4364 orntNew[0] = ornt[0]; 4365 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4366 orntNew[1] = -2; 4367 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 4368 orntNew[2] = ornt[2]; 4369 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 4370 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 4371 #if defined(PETSC_USE_DEBUG) 4372 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); 4373 for (p = 0; p < 3; ++p) { 4374 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); 4375 } 4376 #endif 4377 /* B triangle */ 4378 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 4379 orntNew[0] = ornt[0]; 4380 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 4381 orntNew[1] = ornt[1]; 4382 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4383 orntNew[2] = -2; 4384 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 4385 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 4386 #if defined(PETSC_USE_DEBUG) 4387 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); 4388 for (p = 0; p < 3; ++p) { 4389 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); 4390 } 4391 #endif 4392 /* C triangle */ 4393 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4394 orntNew[0] = -2; 4395 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 4396 orntNew[1] = ornt[1]; 4397 coneNew[2] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 4398 orntNew[2] = ornt[2]; 4399 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 4400 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 4401 #if defined(PETSC_USE_DEBUG) 4402 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); 4403 for (p = 0; p < 3; ++p) { 4404 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); 4405 } 4406 #endif 4407 /* D triangle */ 4408 coneNew[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 4409 orntNew[0] = 0; 4410 coneNew[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 4411 orntNew[1] = 0; 4412 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 4413 orntNew[2] = 0; 4414 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 4415 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 4416 #if defined(PETSC_USE_DEBUG) 4417 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); 4418 for (p = 0; p < 3; ++p) { 4419 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); 4420 } 4421 #endif 4422 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4423 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4424 for (r = 0; r < 4; ++r) { 4425 for (s = 0; s < supportSize; ++s) { 4426 PetscInt subf; 4427 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4428 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4429 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4430 for (c = 0; c < coneSize; ++c) { 4431 if (cone[c] == f) break; 4432 } 4433 subf = GetTriSubfaceInverse_Static(ornt[c], r); 4434 if (support[s] < cMax) { 4435 supportRef[s] = cStartNew + (support[s] - cStart)*8 + (r==3 ? (c+2)%4 + 4 : faces[c*3+subf]); 4436 } else { 4437 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (r==3 ? r : subf); 4438 } 4439 } 4440 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 4441 #if defined(PETSC_USE_DEBUG) 4442 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); 4443 for (p = 0; p < supportSize; ++p) { 4444 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); 4445 } 4446 #endif 4447 } 4448 } 4449 /* Interior cell faces have 3 edges and 2 cells */ 4450 for (c = cStart; c < cMax; ++c) { 4451 PetscInt newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*8; 4452 const PetscInt *cone, *ornt; 4453 PetscInt coneNew[3], orntNew[3]; 4454 PetscInt supportNew[2]; 4455 4456 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4457 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4458 /* Face A: {c, a, d} */ 4459 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4460 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4461 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4462 orntNew[1] = ornt[1] < 0 ? -2 : 0; 4463 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 2); 4464 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4465 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4466 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4467 #if defined(PETSC_USE_DEBUG) 4468 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4469 for (p = 0; p < 3; ++p) { 4470 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); 4471 } 4472 #endif 4473 supportNew[0] = (c - cStart)*8 + 0; 4474 supportNew[1] = (c - cStart)*8 + 0+4; 4475 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4476 #if defined(PETSC_USE_DEBUG) 4477 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4478 for (p = 0; p < 2; ++p) { 4479 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); 4480 } 4481 #endif 4482 ++newp; 4483 /* Face B: {a, b, e} */ 4484 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4485 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4486 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 0); 4487 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4488 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4489 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4490 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4491 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4492 #if defined(PETSC_USE_DEBUG) 4493 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); 4494 for (p = 0; p < 3; ++p) { 4495 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); 4496 } 4497 #endif 4498 supportNew[0] = (c - cStart)*8 + 1; 4499 supportNew[1] = (c - cStart)*8 + 1+4; 4500 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4501 #if defined(PETSC_USE_DEBUG) 4502 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4503 for (p = 0; p < 2; ++p) { 4504 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); 4505 } 4506 #endif 4507 ++newp; 4508 /* Face C: {c, f, b} */ 4509 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4510 orntNew[0] = ornt[2] < 0 ? -2 : 0; 4511 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4512 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4513 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 1); 4514 orntNew[2] = ornt[0] < 0 ? -2 : 0; 4515 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4516 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4517 #if defined(PETSC_USE_DEBUG) 4518 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4519 for (p = 0; p < 3; ++p) { 4520 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); 4521 } 4522 #endif 4523 supportNew[0] = (c - cStart)*8 + 2; 4524 supportNew[1] = (c - cStart)*8 + 2+4; 4525 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4526 #if defined(PETSC_USE_DEBUG) 4527 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4528 for (p = 0; p < 2; ++p) { 4529 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); 4530 } 4531 #endif 4532 ++newp; 4533 /* Face D: {d, e, f} */ 4534 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 0); 4535 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4536 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4537 orntNew[1] = ornt[3] < 0 ? -2 : 0; 4538 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4539 orntNew[2] = ornt[2] < 0 ? -2 : 0; 4540 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4541 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4542 #if defined(PETSC_USE_DEBUG) 4543 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4544 for (p = 0; p < 3; ++p) { 4545 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); 4546 } 4547 #endif 4548 supportNew[0] = (c - cStart)*8 + 3; 4549 supportNew[1] = (c - cStart)*8 + 3+4; 4550 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4551 #if defined(PETSC_USE_DEBUG) 4552 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4553 for (p = 0; p < 2; ++p) { 4554 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); 4555 } 4556 #endif 4557 ++newp; 4558 /* Face E: {d, f, a} */ 4559 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 1); 4560 orntNew[0] = ornt[2] < 0 ? 0 : -2; 4561 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4562 orntNew[1] = -2; 4563 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 2); 4564 orntNew[2] = ornt[1] < 0 ? -2 : 0; 4565 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4566 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4567 #if defined(PETSC_USE_DEBUG) 4568 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4569 for (p = 0; p < 3; ++p) { 4570 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); 4571 } 4572 #endif 4573 supportNew[0] = (c - cStart)*8 + 0+4; 4574 supportNew[1] = (c - cStart)*8 + 3+4; 4575 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4576 #if defined(PETSC_USE_DEBUG) 4577 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4578 for (p = 0; p < 2; ++p) { 4579 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); 4580 } 4581 #endif 4582 ++newp; 4583 /* Face F: {c, a, f} */ 4584 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 2); 4585 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4586 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4587 orntNew[1] = 0; 4588 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriMidEdge_Static(ornt[2], 0); 4589 orntNew[2] = ornt[2] < 0 ? 0 : -2; 4590 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4591 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4592 #if defined(PETSC_USE_DEBUG) 4593 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4594 for (p = 0; p < 3; ++p) { 4595 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); 4596 } 4597 #endif 4598 supportNew[0] = (c - cStart)*8 + 0+4; 4599 supportNew[1] = (c - cStart)*8 + 2+4; 4600 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4601 #if defined(PETSC_USE_DEBUG) 4602 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4603 for (p = 0; p < 2; ++p) { 4604 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); 4605 } 4606 #endif 4607 ++newp; 4608 /* Face G: {e, a, f} */ 4609 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriMidEdge_Static(ornt[1], 1); 4610 orntNew[0] = ornt[1] < 0 ? -2 : 0; 4611 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4612 orntNew[1] = 0; 4613 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 1); 4614 orntNew[2] = ornt[3] < 0 ? 0 : -2; 4615 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4616 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4617 #if defined(PETSC_USE_DEBUG) 4618 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4619 for (p = 0; p < 3; ++p) { 4620 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); 4621 } 4622 #endif 4623 supportNew[0] = (c - cStart)*8 + 1+4; 4624 supportNew[1] = (c - cStart)*8 + 3+4; 4625 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4626 #if defined(PETSC_USE_DEBUG) 4627 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4628 for (p = 0; p < 2; ++p) { 4629 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); 4630 } 4631 #endif 4632 ++newp; 4633 /* Face H: {a, b, f} */ 4634 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriMidEdge_Static(ornt[0], 0); 4635 orntNew[0] = ornt[0] < 0 ? -2 : 0; 4636 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriMidEdge_Static(ornt[3], 2); 4637 orntNew[1] = ornt[3] < 0 ? 0 : -2; 4638 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4639 orntNew[2] = -2; 4640 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4641 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4642 #if defined(PETSC_USE_DEBUG) 4643 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4644 for (p = 0; p < 3; ++p) { 4645 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); 4646 } 4647 #endif 4648 supportNew[0] = (c - cStart)*8 + 1+4; 4649 supportNew[1] = (c - cStart)*8 + 2+4; 4650 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4651 #if defined(PETSC_USE_DEBUG) 4652 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 4653 for (p = 0; p < 2; ++p) { 4654 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); 4655 } 4656 #endif 4657 ++newp; 4658 } 4659 /* Hybrid split faces have 4 edges and same cells */ 4660 for (f = fMax; f < fEnd; ++f) { 4661 const PetscInt *cone, *ornt, *support; 4662 PetscInt coneNew[4], orntNew[4]; 4663 PetscInt supportNew[2], size, s, c; 4664 4665 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4666 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 4667 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4668 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4669 for (r = 0; r < 2; ++r) { 4670 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + r; 4671 4672 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 4673 orntNew[0] = ornt[0]; 4674 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 4675 orntNew[1] = ornt[1]; 4676 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (cone[2+r] - eMax); 4677 orntNew[2+r] = 0; 4678 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4679 orntNew[3-r] = 0; 4680 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4681 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 4682 #if defined(PETSC_USE_DEBUG) 4683 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4684 for (p = 0; p < 2; ++p) { 4685 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); 4686 } 4687 for (p = 2; p < 4; ++p) { 4688 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); 4689 } 4690 #endif 4691 for (s = 0; s < size; ++s) { 4692 const PetscInt *coneCell, *orntCell, *fornt; 4693 PetscInt o, of; 4694 4695 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 4696 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 4697 o = orntCell[0] < 0 ? -1 : 1; 4698 for (c = 2; c < 5; ++c) if (coneCell[c] == f) break; 4699 if (c >= 5) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 4700 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 4701 of = fornt[c-2] < 0 ? -1 : 1; 4702 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetTriEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%3; 4703 } 4704 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4705 #if defined(PETSC_USE_DEBUG) 4706 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 4707 for (p = 0; p < size; ++p) { 4708 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); 4709 } 4710 #endif 4711 } 4712 } 4713 /* Hybrid cell faces have 4 edges and 2 cells */ 4714 for (c = cMax; c < cEnd; ++c) { 4715 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (c - cMax)*3; 4716 const PetscInt *cone, *ornt; 4717 PetscInt coneNew[4], orntNew[4]; 4718 PetscInt supportNew[2]; 4719 4720 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4721 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4722 for (r = 0; r < 3; ++r) { 4723 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + (r+2)%3; 4724 orntNew[0] = 0; 4725 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + (r+2)%3; 4726 orntNew[1] = 0; 4727 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+(r+2)%3] - fMax); 4728 orntNew[2] = 0; 4729 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (cone[2+r] - fMax); 4730 orntNew[3] = 0; 4731 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 4732 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 4733 #if defined(PETSC_USE_DEBUG) 4734 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); 4735 for (p = 0; p < 2; ++p) { 4736 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); 4737 } 4738 for (p = 2; p < 4; ++p) { 4739 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); 4740 } 4741 #endif 4742 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetTriSubface_Static(ornt[0], r); 4743 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + 3; 4744 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 4745 #if defined(PETSC_USE_DEBUG) 4746 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); 4747 for (p = 0; p < 2; ++p) { 4748 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); 4749 } 4750 #endif 4751 } 4752 } 4753 /* Interior split edges have 2 vertices and the same faces as the parent */ 4754 for (e = eStart; e < eMax; ++e) { 4755 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 4756 4757 for (r = 0; r < 2; ++r) { 4758 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 4759 const PetscInt *cone, *ornt, *support; 4760 PetscInt coneNew[2], coneSize, c, supportSize, s; 4761 4762 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4763 coneNew[0] = vStartNew + (cone[0] - vStart); 4764 coneNew[1] = vStartNew + (cone[1] - vStart); 4765 coneNew[(r+1)%2] = newv; 4766 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4767 #if defined(PETSC_USE_DEBUG) 4768 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4769 for (p = 0; p < 2; ++p) { 4770 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); 4771 } 4772 #endif 4773 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 4774 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4775 for (s = 0; s < supportSize; ++s) { 4776 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4777 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4778 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4779 for (c = 0; c < coneSize; ++c) if (cone[c] == e) break; 4780 if (support[s] < fMax) { 4781 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%3; 4782 } else { 4783 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 4784 } 4785 } 4786 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4787 #if defined(PETSC_USE_DEBUG) 4788 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4789 for (p = 0; p < supportSize; ++p) { 4790 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); 4791 } 4792 #endif 4793 } 4794 } 4795 /* Interior face edges have 2 vertices and 2+cells*(1/2) faces */ 4796 for (f = fStart; f < fMax; ++f) { 4797 const PetscInt *cone, *ornt, *support; 4798 PetscInt coneSize, supportSize, s; 4799 4800 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 4801 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4802 for (r = 0; r < 3; ++r) { 4803 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 4804 PetscInt coneNew[2], intFaces = 0, er, eint[4] = {1, 0, 2, 0}; 4805 PetscInt fint[24] = { 1, 7, -1, -1, 0, 5, 4806 -1, -1, 1, 6, 0, 4, 4807 2, 5, 3, 4, -1, -1, 4808 -1, -1, 3, 6, 2, 7}; 4809 4810 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4811 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[(r+0)%3] - eStart); 4812 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[(r+1)%3] - eStart); 4813 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4814 #if defined(PETSC_USE_DEBUG) 4815 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4816 for (p = 0; p < 2; ++p) { 4817 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); 4818 } 4819 #endif 4820 supportRef[0] = fStartNew + (f - fStart)*4 + (r+1)%3; 4821 supportRef[1] = fStartNew + (f - fStart)*4 + 3; 4822 for (s = 0; s < supportSize; ++s) { 4823 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4824 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4825 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 4826 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 4827 if (support[s] < cMax) { 4828 /* Here we want to determine whether edge newp contains a vertex which is part of the cross-tet edge */ 4829 er = GetTriMidEdgeInverse_Static(ornt[c], r); 4830 if (er == eint[c]) { 4831 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + (c + 2)%4; 4832 } else { 4833 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 0]; 4834 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*8 + fint[(c*3 + er)*2 + 1]; 4835 } 4836 } else { 4837 supportRef[2+intFaces++] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (r + 1)%3; 4838 } 4839 } 4840 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4841 #if defined(PETSC_USE_DEBUG) 4842 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4843 for (p = 0; p < intFaces; ++p) { 4844 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); 4845 } 4846 #endif 4847 } 4848 } 4849 /* Interior cell edges have 2 vertices and 4 faces */ 4850 for (c = cStart; c < cMax; ++c) { 4851 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart); 4852 const PetscInt *cone, *ornt, *fcone; 4853 PetscInt coneNew[2], supportNew[4], find; 4854 4855 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 4856 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 4857 ierr = DMPlexGetCone(dm, cone[0], &fcone);CHKERRQ(ierr); 4858 find = GetTriEdge_Static(ornt[0], 0); 4859 coneNew[0] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4860 ierr = DMPlexGetCone(dm, cone[2], &fcone);CHKERRQ(ierr); 4861 find = GetTriEdge_Static(ornt[2], 1); 4862 coneNew[1] = vStartNew + (vEnd - vStart) + (fcone[find] - eStart); 4863 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4864 #if defined(PETSC_USE_DEBUG) 4865 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4866 for (p = 0; p < 2; ++p) { 4867 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); 4868 } 4869 #endif 4870 supportNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 4; 4871 supportNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 5; 4872 supportNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 6; 4873 supportNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*8 + 7; 4874 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 4875 #if defined(PETSC_USE_DEBUG) 4876 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 4877 for (p = 0; p < 4; ++p) { 4878 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); 4879 } 4880 #endif 4881 } 4882 /* Hybrid edges have two vertices and the same faces */ 4883 for (e = eMax; e < eEnd; ++e) { 4884 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (e - eMax); 4885 const PetscInt *cone, *support, *fcone; 4886 PetscInt coneNew[2], size, fsize, s; 4887 4888 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 4889 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4890 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4891 coneNew[0] = vStartNew + (cone[0] - vStart); 4892 coneNew[1] = vStartNew + (cone[1] - vStart); 4893 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4894 #if defined(PETSC_USE_DEBUG) 4895 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4896 for (p = 0; p < 2; ++p) { 4897 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); 4898 } 4899 #endif 4900 for (s = 0; s < size; ++s) { 4901 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 4902 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 4903 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 4904 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 4905 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (support[s] - fMax)*2 + c-2; 4906 } 4907 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4908 #if defined(PETSC_USE_DEBUG) 4909 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4910 for (p = 0; p < size; ++p) { 4911 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); 4912 } 4913 #endif 4914 } 4915 /* Hybrid face edges have 2 vertices and 2+2*cells faces */ 4916 for (f = fMax; f < fEnd; ++f) { 4917 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (f - fMax); 4918 const PetscInt *cone, *support, *ccone, *cornt; 4919 PetscInt coneNew[2], size, csize, s; 4920 4921 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 4922 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 4923 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 4924 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 4925 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 4926 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 4927 #if defined(PETSC_USE_DEBUG) 4928 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4929 for (p = 0; p < 2; ++p) { 4930 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); 4931 } 4932 #endif 4933 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 0; 4934 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (f - fMax)*2 + 1; 4935 for (s = 0; s < size; ++s) { 4936 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 4937 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 4938 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 4939 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 4940 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]); 4941 supportRef[2+s*2+0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c-2; 4942 supportRef[2+s*2+1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + (c-1)%3; 4943 } 4944 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4945 #if defined(PETSC_USE_DEBUG) 4946 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 4947 for (p = 0; p < 2+size*2; ++p) { 4948 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); 4949 } 4950 #endif 4951 } 4952 /* Interior vertices have identical supports */ 4953 for (v = vStart; v < vEnd; ++v) { 4954 const PetscInt newp = vStartNew + (v - vStart); 4955 const PetscInt *support, *cone; 4956 PetscInt size, s; 4957 4958 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 4959 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 4960 for (s = 0; s < size; ++s) { 4961 PetscInt r = 0; 4962 4963 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4964 if (cone[1] == v) r = 1; 4965 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 4966 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (support[s] - eMax); 4967 } 4968 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 4969 #if defined(PETSC_USE_DEBUG) 4970 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 4971 for (p = 0; p < size; ++p) { 4972 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); 4973 } 4974 #endif 4975 } 4976 /* Interior edge vertices have 2 + interior face*2 + hybrid face + cells*0/1 supports */ 4977 for (e = eStart; e < eMax; ++e) { 4978 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 4979 const PetscInt *cone, *support; 4980 PetscInt *star = NULL, starSize, faceSize = 0, cellSize = 0, coneSize, size, s; 4981 4982 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 4983 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 4984 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 4985 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 4986 for (s = 0; s < size; ++s) { 4987 PetscInt r = 0; 4988 4989 if (support[s] < fMax) { 4990 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 4991 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 4992 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 4993 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+0)%3; 4994 supportRef[2+faceSize+1] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + (r+2)%3; 4995 faceSize += 2; 4996 } else { 4997 supportRef[2+faceSize+0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (support[s] - fMax); 4998 ++faceSize; 4999 } 5000 } 5001 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 5002 for (s = 0; s < starSize*2; s += 2) { 5003 const PetscInt *cone, *ornt; 5004 PetscInt e01, e23; 5005 5006 if ((star[s] >= cStart) && (star[s] < cMax)) { 5007 /* Check edge 0-1 */ 5008 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 5009 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 5010 ierr = DMPlexGetCone(dm, cone[0], &cone);CHKERRQ(ierr); 5011 e01 = cone[GetTriEdge_Static(ornt[0], 0)]; 5012 /* Check edge 2-3 */ 5013 ierr = DMPlexGetCone(dm, star[s], &cone);CHKERRQ(ierr); 5014 ierr = DMPlexGetConeOrientation(dm, star[s], &ornt);CHKERRQ(ierr); 5015 ierr = DMPlexGetCone(dm, cone[2], &cone);CHKERRQ(ierr); 5016 e23 = cone[GetTriEdge_Static(ornt[2], 1)]; 5017 if ((e01 == e) || (e23 == e)) {supportRef[2+faceSize+cellSize++] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (star[s] - cStart);} 5018 } 5019 } 5020 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &starSize, &star);CHKERRQ(ierr); 5021 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5022 #if defined(PETSC_USE_DEBUG) 5023 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5024 for (p = 0; p < 2+faceSize+cellSize; ++p) { 5025 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); 5026 } 5027 #endif 5028 } 5029 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5030 ierr = DMPlexRestoreFaces_Internal(dm, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5031 break; 5032 case REFINER_SIMPLEX_TO_HEX_3D: 5033 ierr = DMPlexGetRawFaces_Internal(dm, DM_POLYTOPE_TETRAHEDRON, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5034 /* All cells have 6 faces */ 5035 for (c = cStart; c < cEnd; ++c) { 5036 const PetscInt newp = cStartNew + (c - cStart)*4; 5037 const PetscInt *cone, *ornt; 5038 PetscInt coneNew[6]; 5039 PetscInt orntNew[6]; 5040 5041 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5042 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5043 /* A hex */ 5044 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5045 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5046 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5047 orntNew[1] = -4; 5048 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5049 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5050 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5051 orntNew[3] = -1; 5052 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5053 orntNew[4] = 0; 5054 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5055 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5056 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5057 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5058 #if defined(PETSC_USE_DEBUG) 5059 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); 5060 for (p = 0; p < 6; ++p) { 5061 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); 5062 } 5063 #endif 5064 /* B hex */ 5065 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5066 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5067 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5068 orntNew[1] = 0; 5069 coneNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5070 orntNew[2] = 0; 5071 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5072 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5073 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5074 orntNew[4] = 0; 5075 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5076 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5077 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5078 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5079 #if defined(PETSC_USE_DEBUG) 5080 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); 5081 for (p = 0; p < 6; ++p) { 5082 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); 5083 } 5084 #endif 5085 /* C hex */ 5086 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5087 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5088 coneNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5089 orntNew[1] = -4; 5090 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5091 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5092 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5093 orntNew[3] = -1; 5094 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5095 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5096 coneNew[5] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5097 orntNew[5] = -4; 5098 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5099 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5100 #if defined(PETSC_USE_DEBUG) 5101 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); 5102 for (p = 0; p < 6; ++p) { 5103 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); 5104 } 5105 #endif 5106 /* D hex */ 5107 coneNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5108 orntNew[0] = 0; 5109 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5110 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5111 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5112 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5113 coneNew[3] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5114 orntNew[3] = -1; 5115 coneNew[4] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5116 orntNew[4] = 0; 5117 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5118 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5119 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5120 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5121 #if defined(PETSC_USE_DEBUG) 5122 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); 5123 for (p = 0; p < 6; ++p) { 5124 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); 5125 } 5126 #endif 5127 } 5128 /* Split faces have 4 edges and the same cells as the parent */ 5129 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5130 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5131 for (f = fStart; f < fEnd; ++f) { 5132 const PetscInt newp = fStartNew + (f - fStart)*3; 5133 const PetscInt *cone, *ornt, *support; 5134 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5135 5136 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5137 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5138 /* A quad */ 5139 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5140 orntNew[0] = ornt[2]; 5141 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5142 orntNew[1] = ornt[0]; 5143 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5144 orntNew[2] = 0; 5145 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5146 orntNew[3] = -2; 5147 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5148 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5149 #if defined(PETSC_USE_DEBUG) 5150 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); 5151 for (p = 0; p < 4; ++p) { 5152 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); 5153 } 5154 #endif 5155 /* B quad */ 5156 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5157 orntNew[0] = ornt[0]; 5158 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5159 orntNew[1] = ornt[1]; 5160 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5161 orntNew[2] = 0; 5162 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5163 orntNew[3] = -2; 5164 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5165 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5166 #if defined(PETSC_USE_DEBUG) 5167 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); 5168 for (p = 0; p < 4; ++p) { 5169 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); 5170 } 5171 #endif 5172 /* C quad */ 5173 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5174 orntNew[0] = ornt[1]; 5175 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5176 orntNew[1] = ornt[2]; 5177 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5178 orntNew[2] = 0; 5179 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5180 orntNew[3] = -2; 5181 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5182 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5183 #if defined(PETSC_USE_DEBUG) 5184 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); 5185 for (p = 0; p < 4; ++p) { 5186 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); 5187 } 5188 #endif 5189 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5190 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5191 for (r = 0; r < 3; ++r) { 5192 for (s = 0; s < supportSize; ++s) { 5193 PetscInt subf; 5194 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5195 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5196 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5197 for (c = 0; c < coneSize; ++c) { 5198 if (cone[c] == f) break; 5199 } 5200 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5201 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5202 } 5203 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5204 #if defined(PETSC_USE_DEBUG) 5205 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); 5206 for (p = 0; p < supportSize; ++p) { 5207 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); 5208 } 5209 #endif 5210 } 5211 } 5212 /* Interior faces have 4 edges and 2 cells */ 5213 for (c = cStart; c < cEnd; ++c) { 5214 PetscInt newp = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6; 5215 const PetscInt *cone, *ornt; 5216 PetscInt coneNew[4], orntNew[4]; 5217 PetscInt supportNew[2]; 5218 5219 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5220 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5221 /* Face {a, g, m, h} */ 5222 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5223 orntNew[0] = 0; 5224 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5225 orntNew[1] = 0; 5226 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5227 orntNew[2] = -2; 5228 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5229 orntNew[3] = -2; 5230 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5231 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5232 #if defined(PETSC_USE_DEBUG) 5233 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5234 for (p = 0; p < 4; ++p) { 5235 if ((coneNew[p] < eStartNew) || (coneNew[p] >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", coneNew[p], eStartNew, eEndNew); 5236 } 5237 #endif 5238 supportNew[0] = (c - cStart)*4 + 0; 5239 supportNew[1] = (c - cStart)*4 + 1; 5240 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5241 #if defined(PETSC_USE_DEBUG) 5242 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5243 for (p = 0; p < 2; ++p) { 5244 if ((supportNew[p] < cStartNew) || (supportNew[p] >= cEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a cell [%D, %D)", supportNew[p], cStartNew, cEndNew); 5245 } 5246 #endif 5247 ++newp; 5248 /* Face {g, b, l , m} */ 5249 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5250 orntNew[0] = -2; 5251 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5252 orntNew[1] = 0; 5253 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5254 orntNew[2] = 0; 5255 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5256 orntNew[3] = -2; 5257 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5258 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5259 #if defined(PETSC_USE_DEBUG) 5260 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5261 for (p = 0; p < 4; ++p) { 5262 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); 5263 } 5264 #endif 5265 supportNew[0] = (c - cStart)*4 + 1; 5266 supportNew[1] = (c - cStart)*4 + 2; 5267 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5268 #if defined(PETSC_USE_DEBUG) 5269 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5270 for (p = 0; p < 2; ++p) { 5271 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); 5272 } 5273 #endif 5274 ++newp; 5275 /* Face {c, g, m, i} */ 5276 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5277 orntNew[0] = 0; 5278 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5279 orntNew[1] = 0; 5280 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5281 orntNew[2] = -2; 5282 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5283 orntNew[3] = -2; 5284 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5285 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5286 #if defined(PETSC_USE_DEBUG) 5287 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5288 for (p = 0; p < 4; ++p) { 5289 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); 5290 } 5291 #endif 5292 supportNew[0] = (c - cStart)*4 + 0; 5293 supportNew[1] = (c - cStart)*4 + 2; 5294 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5295 #if defined(PETSC_USE_DEBUG) 5296 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5297 for (p = 0; p < 2; ++p) { 5298 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); 5299 } 5300 #endif 5301 ++newp; 5302 /* Face {d, h, m, i} */ 5303 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5304 orntNew[0] = 0; 5305 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5306 orntNew[1] = 0; 5307 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5308 orntNew[2] = -2; 5309 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5310 orntNew[3] = -2; 5311 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5312 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5313 #if defined(PETSC_USE_DEBUG) 5314 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5315 for (p = 0; p < 4; ++p) { 5316 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); 5317 } 5318 #endif 5319 supportNew[0] = (c - cStart)*4 + 0; 5320 supportNew[1] = (c - cStart)*4 + 3; 5321 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5322 #if defined(PETSC_USE_DEBUG) 5323 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5324 for (p = 0; p < 2; ++p) { 5325 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); 5326 } 5327 #endif 5328 ++newp; 5329 /* Face {h, m, l, e} */ 5330 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5331 orntNew[0] = 0; 5332 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5333 orntNew[1] = -2; 5334 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 5335 orntNew[2] = -2; 5336 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 5337 orntNew[3] = 0; 5338 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5339 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5340 #if defined(PETSC_USE_DEBUG) 5341 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5342 for (p = 0; p < 4; ++p) { 5343 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); 5344 } 5345 #endif 5346 supportNew[0] = (c - cStart)*4 + 1; 5347 supportNew[1] = (c - cStart)*4 + 3; 5348 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5349 #if defined(PETSC_USE_DEBUG) 5350 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5351 for (p = 0; p < 2; ++p) { 5352 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); 5353 } 5354 #endif 5355 ++newp; 5356 /* Face {i, m, l, f} */ 5357 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5358 orntNew[0] = 0; 5359 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5360 orntNew[1] = -2; 5361 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 5362 orntNew[2] = -2; 5363 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 5364 orntNew[3] = 0; 5365 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5366 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5367 #if defined(PETSC_USE_DEBUG) 5368 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5369 for (p = 0; p < 4; ++p) { 5370 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); 5371 } 5372 #endif 5373 supportNew[0] = (c - cStart)*4 + 2; 5374 supportNew[1] = (c - cStart)*4 + 3; 5375 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5376 #if defined(PETSC_USE_DEBUG) 5377 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5378 for (p = 0; p < 2; ++p) { 5379 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); 5380 } 5381 #endif 5382 ++newp; 5383 } 5384 /* Split Edges have 2 vertices and the same faces as the parent */ 5385 for (e = eStart; e < eEnd; ++e) { 5386 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 5387 5388 for (r = 0; r < 2; ++r) { 5389 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 5390 const PetscInt *cone, *ornt, *support; 5391 PetscInt coneNew[2], coneSize, c, supportSize, s; 5392 5393 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 5394 coneNew[0] = vStartNew + (cone[0] - vStart); 5395 coneNew[1] = vStartNew + (cone[1] - vStart); 5396 coneNew[(r+1)%2] = newv; 5397 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5398 #if defined(PETSC_USE_DEBUG) 5399 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5400 for (p = 0; p < 2; ++p) { 5401 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); 5402 } 5403 #endif 5404 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 5405 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5406 for (s = 0; s < supportSize; ++s) { 5407 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5408 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5409 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5410 for (c = 0; c < coneSize; ++c) { 5411 if (cone[c] == e) break; 5412 } 5413 supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 5414 } 5415 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5416 #if defined(PETSC_USE_DEBUG) 5417 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5418 for (p = 0; p < supportSize; ++p) { 5419 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); 5420 } 5421 #endif 5422 } 5423 } 5424 /* Face edges have 2 vertices and 2 + cell faces supports */ 5425 for (f = fStart; f < fEnd; ++f) { 5426 const PetscInt *cone, *ornt, *support; 5427 PetscInt coneSize, supportSize, s; 5428 5429 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5430 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5431 for (r = 0; r < 3; ++r) { 5432 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + r; 5433 PetscInt coneNew[2]; 5434 PetscInt fint[4][3] = { {0, 1, 2}, 5435 {3, 4, 0}, 5436 {2, 5, 3}, 5437 {1, 4, 5} }; 5438 5439 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5440 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 5441 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + f - fStart; 5442 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5443 #if defined(PETSC_USE_DEBUG) 5444 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5445 for (p = 0; p < 2; ++p) { 5446 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); 5447 } 5448 #endif 5449 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 5450 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 5451 for (s = 0; s < supportSize; ++s) { 5452 PetscInt er; 5453 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5454 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5455 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5456 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 5457 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 5458 supportRef[2+s] = fStartNew + (fEnd - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 5459 } 5460 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5461 #if defined(PETSC_USE_DEBUG) 5462 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5463 for (p = 0; p < supportSize + 2; ++p) { 5464 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); 5465 } 5466 #endif 5467 } 5468 } 5469 /* Interior cell edges have 2 vertices and 3 faces */ 5470 for (c = cStart; c < cEnd; ++c) { 5471 const PetscInt *cone; 5472 PetscInt fint[4][3] = { {0,1,2}, 5473 {0,3,4}, 5474 {2,3,5}, 5475 {1,4,5} } ; 5476 5477 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5478 for (r = 0; r < 4; r++) { 5479 PetscInt coneNew[2], supportNew[3]; 5480 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + r; 5481 5482 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 5483 coneNew[1] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd -fStart) + c - cStart; 5484 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5485 #if defined(PETSC_USE_DEBUG) 5486 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5487 for (p = 0; p < 2; ++p) { 5488 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); 5489 } 5490 #endif 5491 supportNew[0] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][0]; 5492 supportNew[1] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][1]; 5493 supportNew[2] = fStartNew + (fEnd - fStart)*3 + (c - cStart)*6 + fint[r][2]; 5494 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5495 #if defined(PETSC_USE_DEBUG) 5496 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 5497 for (p = 0; p < 3; ++p) { 5498 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); 5499 } 5500 #endif 5501 } 5502 } 5503 /* Old vertices have identical supports */ 5504 for (v = vStart; v < vEnd; ++v) { 5505 const PetscInt newp = vStartNew + (v - vStart); 5506 const PetscInt *support, *cone; 5507 PetscInt size, s; 5508 5509 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 5510 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 5511 for (s = 0; s < size; ++s) { 5512 PetscInt r = 0; 5513 5514 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5515 if (cone[1] == v) r = 1; 5516 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 5517 } 5518 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5519 #if defined(PETSC_USE_DEBUG) 5520 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5521 for (p = 0; p < size; ++p) { 5522 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); 5523 } 5524 #endif 5525 } 5526 /* Edge vertices have 2 + faces supports */ 5527 for (e = eStart; e < eEnd; ++e) { 5528 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 5529 const PetscInt *cone, *support; 5530 PetscInt size, s; 5531 5532 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 5533 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 5534 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 5535 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 5536 for (s = 0; s < size; ++s) { 5537 PetscInt r = 0, coneSize; 5538 5539 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5540 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5541 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 5542 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*3 + r; 5543 } 5544 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5545 #if defined(PETSC_USE_DEBUG) 5546 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5547 for (p = 0; p < 2+size; ++p) { 5548 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); 5549 } 5550 #endif 5551 } 5552 /* Face vertices have 3 + cells supports */ 5553 for (f = fStart; f < fEnd; ++f) { 5554 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 5555 const PetscInt *cone, *support; 5556 PetscInt size, s; 5557 5558 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 5559 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5560 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 0; 5561 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 1; 5562 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*3 + 2; 5563 for (s = 0; s < size; ++s) { 5564 PetscInt r = 0, coneSize; 5565 5566 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5567 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5568 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 5569 supportRef[3+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (support[s] - cStart)*4 + r; 5570 } 5571 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5572 #if defined(PETSC_USE_DEBUG) 5573 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5574 for (p = 0; p < 3+size; ++p) { 5575 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); 5576 } 5577 #endif 5578 } 5579 /* Interior cell vertices have 4 supports */ 5580 for (c = cStart; c < cEnd; ++c) { 5581 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + c - cStart; 5582 supportRef[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 0; 5583 supportRef[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 1; 5584 supportRef[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 2; 5585 supportRef[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (c - cStart)*4 + 3; 5586 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 5587 #if defined(PETSC_USE_DEBUG) 5588 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 5589 for (p = 0; p < 4; ++p) { 5590 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); 5591 } 5592 #endif 5593 } 5594 ierr = PetscFree(supportRef);CHKERRQ(ierr); 5595 ierr = DMPlexRestoreFaces_Internal(dm, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 5596 break; 5597 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 5598 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 5599 cMax = PetscMin(cEnd, cMax); 5600 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5601 fMax = PetscMin(fEnd, fMax); 5602 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 5603 eMax = PetscMin(eEnd, eMax); 5604 ierr = DMPlexGetRawFaces_Internal(dm, DM_POLYTOPE_TETRAHEDRON, cellInd, NULL, NULL, &faces);CHKERRQ(ierr); 5605 /* All cells have 6 faces */ 5606 for (c = cStart; c < cMax; ++c) { 5607 const PetscInt newp = cStartNew + (c - cStart)*4; 5608 const PetscInt *cone, *ornt; 5609 PetscInt coneNew[6]; 5610 PetscInt orntNew[6]; 5611 5612 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5613 #if defined(PETSC_USE_DEBUG) 5614 for (p = 0; p < 4; ++p) { 5615 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); 5616 } 5617 #endif 5618 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5619 /* A hex */ 5620 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5621 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5622 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* T */ 5623 orntNew[1] = -4; 5624 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 0); /* F */ 5625 orntNew[2] = ornt[2] < 0 ? -1 : 1; 5626 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* K */ 5627 orntNew[3] = -1; 5628 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* R */ 5629 orntNew[4] = 0; 5630 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* L */ 5631 orntNew[5] = ornt[1] < 0 ? -1 : 1; 5632 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5633 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5634 #if defined(PETSC_USE_DEBUG) 5635 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); 5636 for (p = 0; p < 6; ++p) { 5637 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); 5638 } 5639 #endif 5640 /* B hex */ 5641 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5642 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5643 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* T */ 5644 orntNew[1] = 0; 5645 coneNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 0; /* F */ 5646 orntNew[2] = 0; 5647 coneNew[3] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 1); /* K */ 5648 orntNew[3] = ornt[3] < 0 ? -2 : 0; 5649 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* R */ 5650 orntNew[4] = 0; 5651 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* L */ 5652 orntNew[5] = ornt[1] < 0 ? -4 : 2; 5653 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5654 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5655 #if defined(PETSC_USE_DEBUG) 5656 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); 5657 for (p = 0; p < 6; ++p) { 5658 if ((coneNew[p] < fStartNew) || (coneNew[p] >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", coneNew[p], fStartNew, fEndNew); 5659 } 5660 #endif 5661 /* C hex */ 5662 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5663 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5664 coneNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* T */ 5665 orntNew[1] = -4; 5666 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 1); /* F */ 5667 orntNew[2] = ornt[2] < 0 ? -2 : 0; 5668 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 1; /* K */ 5669 orntNew[3] = -1; 5670 coneNew[4] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 0); /* R */ 5671 orntNew[4] = ornt[3] < 0 ? -1 : 1; 5672 coneNew[5] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 2; /* L */ 5673 orntNew[5] = -4; 5674 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5675 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5676 #if defined(PETSC_USE_DEBUG) 5677 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); 5678 for (p = 0; p < 6; ++p) { 5679 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); 5680 } 5681 #endif 5682 /* D hex */ 5683 coneNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 3; /* B */ 5684 orntNew[0] = 0; 5685 coneNew[1] = fStartNew + (cone[3] - fStart)*3 + GetTriSubface_Static(ornt[3], 2); /* T */ 5686 orntNew[1] = ornt[3] < 0 ? -1 : 1; 5687 coneNew[2] = fStartNew + (cone[2] - fStart)*3 + GetTriSubface_Static(ornt[2], 2); /* F */ 5688 orntNew[2] = ornt[2] < 0 ? -4 : 2; 5689 coneNew[3] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 4; /* K */ 5690 orntNew[3] = -1; 5691 coneNew[4] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + 5; /* R */ 5692 orntNew[4] = 0; 5693 coneNew[5] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* L */ 5694 orntNew[5] = ornt[1] < 0 ? -2 : 0; 5695 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 5696 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 5697 #if defined(PETSC_USE_DEBUG) 5698 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); 5699 for (p = 0; p < 6; ++p) { 5700 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); 5701 } 5702 #endif 5703 } 5704 for (c = cMax; c < cEnd; ++c) { 5705 const PetscInt newp = cStartNew + (cMax - cStart)*4 + (c - cMax)*3; 5706 const PetscInt *cone, *ornt; 5707 PetscInt coneNew[6], orntNew[6]; 5708 PetscInt o, of, cf; 5709 5710 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5711 #if defined(PETSC_USE_DEBUG) 5712 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); 5713 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); 5714 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); 5715 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); 5716 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); 5717 #endif 5718 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5719 o = ornt[0] < 0 ? -1 : 1; 5720 o = 1; 5721 /* A hex */ 5722 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 0); /* B */ 5723 orntNew[0] = ornt[0] < 0 ? -1 : 1; 5724 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 0); /* T */ 5725 orntNew[1] = ornt[1] < 0 ? 1 : -1; 5726 cf = 2; 5727 of = ornt[2+cf] < 0 ? -1 : 1; 5728 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* F */ 5729 orntNew[2] = o*of < 0 ? 0 : -1; 5730 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* K */ 5731 orntNew[3] = -1; 5732 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* R */ 5733 orntNew[4] = 0; 5734 cf = 0; 5735 of = ornt[2+cf] < 0 ? -1 : 1; 5736 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* L */ 5737 orntNew[5] = o*of < 0 ? 1 : -4; 5738 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5739 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5740 #if defined(PETSC_USE_DEBUG) 5741 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); 5742 for (p = 0; p < 6; ++p) { 5743 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); 5744 } 5745 #endif 5746 /* B hex */ 5747 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 1); /* B */ 5748 orntNew[0] = ornt[0] < 0 ? -2 : 0; 5749 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 1); /* T */ 5750 orntNew[1] = ornt[1] < 0 ? 2 : -4; 5751 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; /* F */ 5752 orntNew[2] = 0; 5753 cf = 1; 5754 of = ornt[2+cf] < 0 ? -1 : 1; 5755 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* K */ 5756 orntNew[3] = o*of < 0 ? 0 : -1; 5757 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* R */ 5758 orntNew[4] = -1; 5759 cf = 0; 5760 of = ornt[2+cf] < 0 ? -1 : 1; 5761 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* L */ 5762 orntNew[5] = o*of < 0 ? 1 : -4; 5763 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5764 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5765 #if defined(PETSC_USE_DEBUG) 5766 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); 5767 for (p = 0; p < 6; ++p) { 5768 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); 5769 } 5770 #endif 5771 /* C hex */ 5772 coneNew[0] = fStartNew + (cone[0] - fStart)*3 + GetTriSubface_Static(ornt[0], 2); /* B */ 5773 orntNew[0] = ornt[0] < 0 ? -4 : 2; 5774 coneNew[1] = fStartNew + (cone[1] - fStart)*3 + GetTriSubface_Static(ornt[1], 2); /* T */ 5775 orntNew[1] = ornt[1] < 0 ? 0 : -2; 5776 cf = 2; 5777 of = ornt[2+cf] < 0 ? -1 : 1; 5778 coneNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 1 : 0); /* F */ 5779 orntNew[2] = o*of < 0 ? 0 : -1; 5780 coneNew[3] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; /* K */ 5781 orntNew[3] = 0; 5782 cf = 1; 5783 of = ornt[2+cf] < 0 ? -1 : 1; 5784 coneNew[4] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (cone[2+cf] - fMax)*2 + (o*of < 0 ? 0 : 1); /* R */ 5785 orntNew[4] = o*of < 0 ? 0 : -1; 5786 coneNew[5] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; /* L */ 5787 orntNew[5] = -4; 5788 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5789 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5790 #if defined(PETSC_USE_DEBUG) 5791 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); 5792 for (p = 0; p < 6; ++p) { 5793 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); 5794 } 5795 #endif 5796 } 5797 5798 /* Split faces have 4 edges and the same cells as the parent */ 5799 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 5800 ierr = PetscMalloc1(2 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 5801 for (f = fStart; f < fMax; ++f) { 5802 const PetscInt newp = fStartNew + (f - fStart)*3; 5803 const PetscInt *cone, *ornt, *support; 5804 PetscInt coneNew[4], orntNew[4], coneSize, supportSize, s; 5805 5806 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 5807 #if defined(PETSC_USE_DEBUG) 5808 for (p = 0; p < 3; ++p) { 5809 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); 5810 } 5811 #endif 5812 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 5813 /* A quad */ 5814 coneNew[0] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 0 : 1); 5815 orntNew[0] = ornt[2]; 5816 coneNew[1] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 5817 orntNew[1] = ornt[0]; 5818 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5819 orntNew[2] = 0; 5820 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5821 orntNew[3] = -2; 5822 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 5823 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 5824 #if defined(PETSC_USE_DEBUG) 5825 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); 5826 for (p = 0; p < 4; ++p) { 5827 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); 5828 } 5829 #endif 5830 /* B quad */ 5831 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 5832 orntNew[0] = ornt[0]; 5833 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 5834 orntNew[1] = ornt[1]; 5835 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5836 orntNew[2] = 0; 5837 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 5838 orntNew[3] = -2; 5839 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 5840 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 5841 #if defined(PETSC_USE_DEBUG) 5842 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); 5843 for (p = 0; p < 4; ++p) { 5844 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); 5845 } 5846 #endif 5847 /* C quad */ 5848 coneNew[0] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 5849 orntNew[0] = ornt[1]; 5850 coneNew[1] = eStartNew + (cone[2] - eStart)*2 + (ornt[2] < 0 ? 1 : 0); 5851 orntNew[1] = ornt[2]; 5852 coneNew[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 5853 orntNew[2] = 0; 5854 coneNew[3] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 5855 orntNew[3] = -2; 5856 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 5857 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 5858 #if defined(PETSC_USE_DEBUG) 5859 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); 5860 for (p = 0; p < 4; ++p) { 5861 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); 5862 } 5863 #endif 5864 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 5865 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 5866 for (r = 0; r < 3; ++r) { 5867 for (s = 0; s < supportSize; ++s) { 5868 PetscInt subf; 5869 5870 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 5871 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); 5872 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); 5873 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 5874 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 5875 for (c = 0; c < coneSize; ++c) { 5876 if (cone[c] == f) break; 5877 } 5878 subf = GetTriSubfaceInverse_Static(ornt[c], r); 5879 if (coneSize == 4) { 5880 supportRef[s] = cStartNew + (support[s] - cStart)*4 + faces[c*3+subf]; 5881 } else if (coneSize == 5) { 5882 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); 5883 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + subf; 5884 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for cell %D (cMax %D)", coneSize, support[s], cMax); 5885 } 5886 ierr = DMPlexSetSupport(rdm, newp+r, supportRef);CHKERRQ(ierr); 5887 #if defined(PETSC_USE_DEBUG) 5888 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); 5889 for (p = 0; p < supportSize; ++p) { 5890 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); 5891 } 5892 #endif 5893 } 5894 } 5895 /* Interior faces have 4 edges and 2 cells */ 5896 for (c = cStart; c < cMax; ++c) { 5897 PetscInt newp = fStartNew + (fMax - fStart)*3 + (c - cStart)*6; 5898 const PetscInt *cone, *ornt; 5899 PetscInt coneNew[4], orntNew[4]; 5900 PetscInt supportNew[2]; 5901 5902 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 5903 #if defined(PETSC_USE_DEBUG) 5904 for (p = 0; p < 4; ++p) { 5905 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); 5906 } 5907 #endif 5908 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 5909 /* Face {a, g, m, h} */ 5910 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 5911 orntNew[0] = 0; 5912 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5913 orntNew[1] = 0; 5914 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5915 orntNew[2] = -2; 5916 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 5917 orntNew[3] = -2; 5918 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5919 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5920 #if defined(PETSC_USE_DEBUG) 5921 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5922 for (p = 0; p < 4; ++p) { 5923 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); 5924 } 5925 #endif 5926 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5927 supportNew[1] = cStartNew + (c - cStart)*4 + 1; 5928 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5929 #if defined(PETSC_USE_DEBUG) 5930 for (p = 0; p < 2; ++p) { 5931 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); 5932 } 5933 #endif 5934 ++newp; 5935 /* Face {g, b, l , m} */ 5936 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 5937 orntNew[0] = -2; 5938 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],0); 5939 orntNew[1] = 0; 5940 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 5941 orntNew[2] = 0; 5942 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5943 orntNew[3] = -2; 5944 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5945 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5946 #if defined(PETSC_USE_DEBUG) 5947 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5948 for (p = 0; p < 4; ++p) { 5949 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); 5950 } 5951 #endif 5952 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 5953 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5954 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5955 #if defined(PETSC_USE_DEBUG) 5956 for (p = 0; p < 2; ++p) { 5957 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); 5958 } 5959 #endif 5960 ++newp; 5961 /* Face {c, g, m, i} */ 5962 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 5963 orntNew[0] = 0; 5964 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 5965 orntNew[1] = 0; 5966 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5967 orntNew[2] = -2; 5968 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],0); 5969 orntNew[3] = -2; 5970 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5971 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5972 #if defined(PETSC_USE_DEBUG) 5973 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 5974 for (p = 0; p < 4; ++p) { 5975 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); 5976 } 5977 #endif 5978 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 5979 supportNew[1] = cStartNew + (c - cStart)*4 + 2; 5980 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 5981 #if defined(PETSC_USE_DEBUG) 5982 for (p = 0; p < 2; ++p) { 5983 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); 5984 } 5985 #endif 5986 ++newp; 5987 /* Face {d, h, m, i} */ 5988 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 5989 orntNew[0] = 0; 5990 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 5991 orntNew[1] = 0; 5992 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 5993 orntNew[2] = -2; 5994 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],2); 5995 orntNew[3] = -2; 5996 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 5997 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 5998 #if defined(PETSC_USE_DEBUG) 5999 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6000 for (p = 0; p < 4; ++p) { 6001 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); 6002 } 6003 #endif 6004 supportNew[0] = cStartNew + (c - cStart)*4 + 0; 6005 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6006 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6007 #if defined(PETSC_USE_DEBUG) 6008 for (p = 0; p < 2; ++p) { 6009 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); 6010 } 6011 #endif 6012 ++newp; 6013 /* Face {h, m, l, e} */ 6014 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6015 orntNew[0] = 0; 6016 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6017 orntNew[1] = -2; 6018 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],1); 6019 orntNew[2] = -2; 6020 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6021 orntNew[3] = 0; 6022 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6023 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6024 #if defined(PETSC_USE_DEBUG) 6025 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6026 for (p = 0; p < 4; ++p) { 6027 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); 6028 } 6029 #endif 6030 supportNew[0] = cStartNew + (c - cStart)*4 + 1; 6031 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6032 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6033 #if defined(PETSC_USE_DEBUG) 6034 for (p = 0; p < 2; ++p) { 6035 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); 6036 } 6037 #endif 6038 ++newp; 6039 /* Face {i, m, l, f} */ 6040 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6041 orntNew[0] = 0; 6042 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6043 orntNew[1] = -2; 6044 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*3 + GetTriInteriorEdge_Static(ornt[3],2); 6045 orntNew[2] = -2; 6046 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*3 + GetTriInteriorEdge_Static(ornt[2],1); 6047 orntNew[3] = 0; 6048 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6049 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6050 #if defined(PETSC_USE_DEBUG) 6051 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6052 for (p = 0; p < 4; ++p) { 6053 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); 6054 } 6055 #endif 6056 supportNew[0] = cStartNew + (c - cStart)*4 + 2; 6057 supportNew[1] = cStartNew + (c - cStart)*4 + 3; 6058 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6059 #if defined(PETSC_USE_DEBUG) 6060 for (p = 0; p < 2; ++p) { 6061 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); 6062 } 6063 #endif 6064 ++newp; 6065 } 6066 /* Hybrid split faces have 4 edges and same cells */ 6067 for (f = fMax; f < fEnd; ++f) { 6068 const PetscInt *cone, *ornt, *support; 6069 PetscInt coneNew[4], orntNew[4]; 6070 PetscInt size, s; 6071 const PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f - fMax)*2; 6072 6073 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6074 #if defined(PETSC_USE_DEBUG) 6075 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); 6076 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); 6077 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); 6078 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); 6079 #endif 6080 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6081 /* A face */ 6082 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1 : 0); 6083 orntNew[0] = ornt[0]; 6084 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 6085 orntNew[1] = 0; 6086 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1 : 0); 6087 orntNew[2] = ornt[1] < 0 ? 0 : -2; 6088 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[2] - eMax); 6089 orntNew[3] = ornt[2] < 0 ? 0 : -2; 6090 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6091 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6092 #if defined(PETSC_USE_DEBUG) 6093 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6094 for (p = 0; p < 4; ++p) { 6095 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); 6096 } 6097 #endif 6098 6099 /* B face */ 6100 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 0 : 1); 6101 orntNew[0] = ornt[0]; 6102 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (cone[3] - eMax); 6103 orntNew[1] = ornt[3]; 6104 coneNew[2] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 0 : 1); 6105 orntNew[2] = ornt[1] < 0 ? 0 : -2; 6106 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (f - fMax); 6107 orntNew[3] = -2; 6108 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6109 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6110 #if defined(PETSC_USE_DEBUG) 6111 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); 6112 for (p = 0; p < 4; ++p) { 6113 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); 6114 } 6115 #endif 6116 6117 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6118 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6119 for (r = 0; r < 2; ++r) { 6120 for (s = 0; s < size; ++s) { 6121 const PetscInt *coneCell, *orntCell; 6122 PetscInt coneSize, o, of, c; 6123 6124 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6125 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); 6126 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 6127 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 6128 o = orntCell[0] < 0 ? -1 : 1; 6129 o = 1; 6130 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 6131 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); 6132 if (c == coneSize) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 6133 of = orntCell[c] < 0 ? -1 : 1; 6134 supportRef[s] = cStartNew + (cMax - cStart)*4 + (support[s] - cMax)*3 + (c-2 + (o*of < 0 ? 1-r : r))%3; 6135 } 6136 ierr = DMPlexSetSupport(rdm, newp + r, supportRef);CHKERRQ(ierr); 6137 #if defined(PETSC_USE_DEBUG) 6138 for (p = 0; p < size; ++p) { 6139 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); 6140 } 6141 #endif 6142 } 6143 } 6144 /* Interior hybrid faces have 4 edges and 2 cells */ 6145 for (c = cMax; c < cEnd; ++c) { 6146 PetscInt newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3; 6147 const PetscInt *cone, *ornt; 6148 PetscInt coneNew[4], orntNew[4]; 6149 PetscInt supportNew[2]; 6150 6151 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6152 #if defined(PETSC_USE_DEBUG) 6153 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); 6154 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); 6155 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); 6156 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); 6157 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); 6158 #endif 6159 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6160 /* Face {a, g, h, d} */ 6161 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],0); 6162 orntNew[0] = 0; 6163 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6164 orntNew[1] = 0; 6165 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],0); 6166 orntNew[2] = -2; 6167 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[2] - fMax); 6168 orntNew[3] = -2; 6169 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6170 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6171 #if defined(PETSC_USE_DEBUG) 6172 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6173 for (p = 0; p < 4; ++p) { 6174 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); 6175 } 6176 #endif 6177 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6178 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6179 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6180 #if defined(PETSC_USE_DEBUG) 6181 for (p = 0; p < 2; ++p) { 6182 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); 6183 } 6184 #endif 6185 ++newp; 6186 /* Face {b, g, h, l} */ 6187 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],1); 6188 orntNew[0] = 0; 6189 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6190 orntNew[1] = 0; 6191 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],1); 6192 orntNew[2] = -2; 6193 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[3] - fMax); 6194 orntNew[3] = -2; 6195 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6196 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6197 #if defined(PETSC_USE_DEBUG) 6198 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6199 for (p = 0; p < 4; ++p) { 6200 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); 6201 } 6202 #endif 6203 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 1; 6204 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6205 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6206 #if defined(PETSC_USE_DEBUG) 6207 for (p = 0; p < 2; ++p) { 6208 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); 6209 } 6210 #endif 6211 ++newp; 6212 /* Face {c, g, h, f} */ 6213 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*3 + GetTriInteriorEdge_Static(ornt[0],2); 6214 orntNew[0] = 0; 6215 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6216 orntNew[1] = 0; 6217 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*3 + GetTriInteriorEdge_Static(ornt[1],2); 6218 orntNew[2] = -2; 6219 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (cone[4] - fMax); 6220 orntNew[3] = -2; 6221 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6222 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6223 #if defined(PETSC_USE_DEBUG) 6224 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6225 for (p = 0; p < 4; ++p) { 6226 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); 6227 } 6228 #endif 6229 supportNew[0] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 2; 6230 supportNew[1] = cStartNew + (cMax - cStart)*4 + (c - cMax)*3 + 0; 6231 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6232 #if defined(PETSC_USE_DEBUG) 6233 for (p = 0; p < 2; ++p) { 6234 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); 6235 } 6236 #endif 6237 } 6238 /* Face edges have 2 vertices and 2 + cell faces supports */ 6239 for (f = fStart; f < fMax; ++f) { 6240 const PetscInt *cone, *ornt, *support; 6241 PetscInt coneSize, supportSize, s; 6242 6243 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6244 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6245 for (r = 0; r < 3; ++r) { 6246 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + r; 6247 PetscInt coneNew[2]; 6248 PetscInt fint[4][3] = { {0, 1, 2}, 6249 {3, 4, 0}, 6250 {2, 5, 3}, 6251 {1, 4, 5} }; 6252 6253 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6254 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); 6255 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 6256 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + f - fStart; 6257 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6258 #if defined(PETSC_USE_DEBUG) 6259 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6260 for (p = 0; p < 2; ++p) { 6261 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); 6262 } 6263 #endif 6264 supportRef[0] = fStartNew + (f - fStart)*3 + (r+0)%3; 6265 supportRef[1] = fStartNew + (f - fStart)*3 + (r+1)%3; 6266 for (s = 0; s < supportSize; ++s) { 6267 PetscInt er; 6268 6269 supportRef[2+s] = -1; 6270 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6271 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); 6272 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); 6273 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6274 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6275 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6276 er = GetTriInteriorEdgeInverse_Static(ornt[c], r); 6277 if (coneSize == 4) { 6278 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (support[s] - cStart)*6 + fint[c][er]; 6279 } else if (coneSize == 5) { 6280 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); 6281 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + er; 6282 } 6283 } 6284 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6285 #if defined(PETSC_USE_DEBUG) 6286 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6287 for (p = 0; p < supportSize + 2; ++p) { 6288 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); 6289 } 6290 #endif 6291 } 6292 } 6293 /* Interior cell edges have 2 vertices and 3 faces */ 6294 for (c = cStart; c < cMax; ++c) { 6295 const PetscInt *cone; 6296 PetscInt fint[4][3] = { {0,1,2}, 6297 {0,3,4}, 6298 {2,3,5}, 6299 {1,4,5} } ; 6300 6301 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6302 for (r = 0; r < 4; r++) { 6303 PetscInt coneNew[2], supportNew[3]; 6304 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + r; 6305 6306 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); 6307 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 6308 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax -fStart) + c - cStart; 6309 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6310 #if defined(PETSC_USE_DEBUG) 6311 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6312 for (p = 0; p < 2; ++p) { 6313 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); 6314 } 6315 #endif 6316 supportNew[0] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][0]; 6317 supportNew[1] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][1]; 6318 supportNew[2] = fStartNew + (fMax - fStart)*3 + (c - cStart)*6 + fint[r][2]; 6319 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6320 #if defined(PETSC_USE_DEBUG) 6321 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6322 for (p = 0; p < 3; ++p) { 6323 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); 6324 } 6325 #endif 6326 } 6327 } 6328 /* Hybrid edges have two vertices and the same faces */ 6329 for (e = eMax; e < eEnd; ++e) { 6330 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (e - eMax); 6331 const PetscInt *cone, *support, *fcone; 6332 PetscInt coneNew[2], size, fsize, s; 6333 6334 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6335 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6336 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6337 coneNew[0] = vStartNew + (cone[0] - vStart); 6338 coneNew[1] = vStartNew + (cone[1] - vStart); 6339 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6340 #if defined(PETSC_USE_DEBUG) 6341 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is a edge [%D, %D)", newp, eStartNew, eEndNew); 6342 for (p = 0; p < 2; ++p) { 6343 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); 6344 } 6345 #endif 6346 for (s = 0; s < size; ++s) { 6347 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 6348 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 6349 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 6350 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 6351 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + c-2; 6352 } 6353 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6354 #if defined(PETSC_USE_DEBUG) 6355 for (p = 0; p < size; ++p) { 6356 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); 6357 } 6358 #endif 6359 } 6360 /* Hybrid face edges have 2 vertices and 2 + cell faces supports */ 6361 for (f = fMax; f < fEnd; ++f) { 6362 const PetscInt *cone, *ornt, *support; 6363 PetscInt coneSize, supportSize; 6364 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + f - fMax; 6365 PetscInt coneNew[2], s; 6366 6367 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6368 #if defined(PETSC_USE_DEBUG) 6369 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); 6370 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); 6371 #endif 6372 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 6373 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 6374 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6375 #if defined(PETSC_USE_DEBUG) 6376 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6377 for (p = 0; p < 2; ++p) { 6378 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); 6379 } 6380 #endif 6381 supportRef[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 0; 6382 supportRef[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (f- fMax)*2 + 1; 6383 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6384 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6385 for (s = 0; s < supportSize; ++s) { 6386 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6387 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); 6388 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6389 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6390 for (c = 0; c < coneSize; ++c) {if (cone[c] == f) break;} 6391 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); 6392 supportRef[2+s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (support[s] - cMax)*3 + c - 2; 6393 } 6394 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6395 #if defined(PETSC_USE_DEBUG) 6396 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6397 for (p = 0; p < supportSize + 2; ++p) { 6398 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); 6399 } 6400 #endif 6401 } 6402 /* Hybrid cell edges have 2 vertices and 3 faces */ 6403 for (c = cMax; c < cEnd; ++c) { 6404 PetscInt coneNew[2], supportNew[3]; 6405 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + c - cMax; 6406 const PetscInt *cone; 6407 6408 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6409 #if defined(PETSC_USE_DEBUG) 6410 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); 6411 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); 6412 #endif 6413 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 6414 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 6415 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6416 #if defined(PETSC_USE_DEBUG) 6417 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6418 for (p = 0; p < 2; ++p) { 6419 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); 6420 } 6421 #endif 6422 supportNew[0] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 0; 6423 supportNew[1] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 1; 6424 supportNew[2] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (c - cMax)*3 + 2; 6425 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 6426 #if defined(PETSC_USE_DEBUG) 6427 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6428 for (p = 0; p < 3; ++p) { 6429 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); 6430 } 6431 #endif 6432 } 6433 /* Old vertices have identical supports */ 6434 for (v = vStart; v < vEnd; ++v) { 6435 const PetscInt newp = vStartNew + (v - vStart); 6436 const PetscInt *support, *cone; 6437 PetscInt size, s; 6438 6439 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 6440 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 6441 for (s = 0; s < size; ++s) { 6442 const PetscInt e = support[s]; 6443 6444 supportRef[s] = -1; 6445 if (eStart <= e) { 6446 if (e < eMax) { 6447 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6448 supportRef[s] = eStartNew + (e - eStart)*2 + (cone[1] == v ? 1 : 0); 6449 } else if (e < eEnd) { 6450 supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + e - eMax; 6451 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6452 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", e, eStart, eEnd); 6453 } 6454 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6455 #if defined(PETSC_USE_DEBUG) 6456 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6457 for (p = 0; p < size; ++p) { 6458 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); 6459 } 6460 #endif 6461 } 6462 /* Interior edge vertices have 2 + faces supports */ 6463 for (e = eStart; e < eMax; ++e) { 6464 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 6465 const PetscInt *cone, *support; 6466 PetscInt size, s; 6467 6468 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 6469 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6470 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 6471 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 6472 for (s = 0; s < size; ++s) { 6473 PetscInt r, coneSize; 6474 6475 supportRef[2+s] = -1; 6476 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6477 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); 6478 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); 6479 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6480 for (r = 0; r < coneSize; ++r) {if (cone[r] == e) break;} 6481 if (coneSize == 3) supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*3 + r; 6482 else if (coneSize == 4) { 6483 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); 6484 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + support[s] - fMax; 6485 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6486 } 6487 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6488 #if defined(PETSC_USE_DEBUG) 6489 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6490 for (p = 0; p < 2+size; ++p) { 6491 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); 6492 } 6493 #endif 6494 } 6495 /* Split Edges have 2 vertices and the same faces as the parent */ 6496 for (e = eStart; e < eMax; ++e) { 6497 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 6498 6499 for (r = 0; r < 2; ++r) { 6500 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 6501 const PetscInt *cone, *ornt, *support; 6502 PetscInt coneNew[2], coneSize, c, supportSize, s; 6503 6504 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 6505 coneNew[0] = vStartNew + (cone[0] - vStart); 6506 coneNew[1] = vStartNew + (cone[1] - vStart); 6507 coneNew[(r+1)%2] = newv; 6508 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6509 #if defined(PETSC_USE_DEBUG) 6510 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6511 for (p = 0; p < 2; ++p) { 6512 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); 6513 } 6514 #endif 6515 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 6516 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 6517 for (s = 0; s < supportSize; ++s) { 6518 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6519 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); 6520 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); 6521 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6522 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6523 for (c = 0; c < coneSize; ++c) { 6524 if (cone[c] == e) break; 6525 } 6526 if (coneSize == 3) supportRef[s] = fStartNew + (support[s] - fStart)*3 + (c + (ornt[c] < 0 ? 1-r : r))%3; 6527 else if (coneSize == 4) { 6528 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); 6529 supportRef[s] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 6530 } else SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Unexpected conesize %D for face %D (fMax %D)", coneSize, support[s], fMax); 6531 } 6532 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6533 #if defined(PETSC_USE_DEBUG) 6534 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 6535 for (p = 0; p < supportSize; ++p) { 6536 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); 6537 } 6538 #endif 6539 } 6540 } 6541 /* Face vertices have 3 + cells supports */ 6542 for (f = fStart; f < fMax; ++f) { 6543 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 6544 const PetscInt *cone, *support; 6545 PetscInt size, s; 6546 6547 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 6548 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6549 supportRef[0] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 0; 6550 supportRef[1] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 1; 6551 supportRef[2] = eStartNew + (eMax - eStart)*2 + (f - fStart)*3 + 2; 6552 for (s = 0; s < size; ++s) { 6553 PetscInt r, coneSize; 6554 6555 supportRef[3+s] = -1; 6556 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6557 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); 6558 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); 6559 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6560 for (r = 0; r < coneSize; ++r) {if (cone[r] == f) break;} 6561 if (coneSize == 4) supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (support[s] - cStart)*4 + r; 6562 else if (coneSize == 5) { 6563 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); 6564 supportRef[3+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + support[s] - cMax; 6565 } 6566 } 6567 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6568 #if defined(PETSC_USE_DEBUG) 6569 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6570 for (p = 0; p < 3+size; ++p) { 6571 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); 6572 } 6573 #endif 6574 } 6575 /* Interior cell vertices have 4 supports */ 6576 for (c = cStart; c < cMax; ++c) { 6577 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + c - cStart; 6578 6579 supportRef[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 0; 6580 supportRef[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 1; 6581 supportRef[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 2; 6582 supportRef[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (c - cStart)*4 + 3; 6583 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6584 #if defined(PETSC_USE_DEBUG) 6585 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 6586 for (p = 0; p < 4; ++p) { 6587 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); 6588 } 6589 #endif 6590 } 6591 ierr = PetscFree(supportRef);CHKERRQ(ierr); 6592 ierr = DMPlexRestoreFaces_Internal(dm, cStart, NULL, NULL, &faces);CHKERRQ(ierr); 6593 break; 6594 case REFINER_HEX_3D: 6595 /* 6596 Bottom (viewed from top) Top 6597 1---------2---------2 7---------2---------6 6598 | | | | | | 6599 | B 2 C | | H 2 G | 6600 | | | | | | 6601 3----3----0----1----1 3----3----0----1----1 6602 | | | | | | 6603 | A 0 D | | E 0 F | 6604 | | | | | | 6605 0---------0---------3 4---------0---------5 6606 */ 6607 /* All cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 6608 for (c = cStart; c < cEnd; ++c) { 6609 const PetscInt newp = (c - cStart)*8; 6610 const PetscInt *cone, *ornt; 6611 PetscInt coneNew[6], orntNew[6]; 6612 6613 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6614 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6615 /* A hex */ 6616 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 6617 orntNew[0] = ornt[0]; 6618 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6619 orntNew[1] = 0; 6620 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 6621 orntNew[2] = ornt[2]; 6622 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6623 orntNew[3] = 0; 6624 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6625 orntNew[4] = 0; 6626 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 6627 orntNew[5] = ornt[5]; 6628 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 6629 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 6630 #if defined(PETSC_USE_DEBUG) 6631 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); 6632 for (p = 0; p < 6; ++p) { 6633 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); 6634 } 6635 #endif 6636 /* B hex */ 6637 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 6638 orntNew[0] = ornt[0]; 6639 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6640 orntNew[1] = 0; 6641 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 6642 orntNew[2] = -1; 6643 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 6644 orntNew[3] = ornt[3]; 6645 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6646 orntNew[4] = 0; 6647 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 6648 orntNew[5] = ornt[5]; 6649 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 6650 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 6651 #if defined(PETSC_USE_DEBUG) 6652 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); 6653 for (p = 0; p < 6; ++p) { 6654 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); 6655 } 6656 #endif 6657 /* C hex */ 6658 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 6659 orntNew[0] = ornt[0]; 6660 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6661 orntNew[1] = 0; 6662 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6663 orntNew[2] = -1; 6664 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 6665 orntNew[3] = ornt[3]; 6666 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 6667 orntNew[4] = ornt[4]; 6668 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 6669 orntNew[5] = -4; 6670 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 6671 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 6672 #if defined(PETSC_USE_DEBUG) 6673 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); 6674 for (p = 0; p < 6; ++p) { 6675 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); 6676 } 6677 #endif 6678 /* D hex */ 6679 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 6680 orntNew[0] = ornt[0]; 6681 coneNew[1] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6682 orntNew[1] = 0; 6683 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 6684 orntNew[2] = ornt[2]; 6685 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 6686 orntNew[3] = 0; 6687 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 6688 orntNew[4] = ornt[4]; 6689 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 6690 orntNew[5] = -4; 6691 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 6692 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 6693 #if defined(PETSC_USE_DEBUG) 6694 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); 6695 for (p = 0; p < 6; ++p) { 6696 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); 6697 } 6698 #endif 6699 /* E hex */ 6700 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 6701 orntNew[0] = -4; 6702 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 6703 orntNew[1] = ornt[1]; 6704 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 6705 orntNew[2] = ornt[2]; 6706 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6707 orntNew[3] = 0; 6708 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6709 orntNew[4] = -1; 6710 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 6711 orntNew[5] = ornt[5]; 6712 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 6713 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 6714 #if defined(PETSC_USE_DEBUG) 6715 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); 6716 for (p = 0; p < 6; ++p) { 6717 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); 6718 } 6719 #endif 6720 /* F hex */ 6721 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 6722 orntNew[0] = -4; 6723 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 6724 orntNew[1] = ornt[1]; 6725 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 6726 orntNew[2] = ornt[2]; 6727 coneNew[3] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6728 orntNew[3] = -1; 6729 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 6730 orntNew[4] = ornt[4]; 6731 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 6732 orntNew[5] = 1; 6733 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 6734 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 6735 #if defined(PETSC_USE_DEBUG) 6736 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); 6737 for (p = 0; p < 6; ++p) { 6738 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); 6739 } 6740 #endif 6741 /* G hex */ 6742 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 6743 orntNew[0] = -4; 6744 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 6745 orntNew[1] = ornt[1]; 6746 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 6747 orntNew[2] = 0; 6748 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 6749 orntNew[3] = ornt[3]; 6750 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 6751 orntNew[4] = ornt[4]; 6752 coneNew[5] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6753 orntNew[5] = -3; 6754 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 6755 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 6756 #if defined(PETSC_USE_DEBUG) 6757 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); 6758 for (p = 0; p < 6; ++p) { 6759 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); 6760 } 6761 #endif 6762 /* H hex */ 6763 coneNew[0] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 6764 orntNew[0] = -4; 6765 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 6766 orntNew[1] = ornt[1]; 6767 coneNew[2] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 6768 orntNew[2] = -1; 6769 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 6770 orntNew[3] = ornt[3]; 6771 coneNew[4] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 6772 orntNew[4] = 3; 6773 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 6774 orntNew[5] = ornt[5]; 6775 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 6776 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 6777 #if defined(PETSC_USE_DEBUG) 6778 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); 6779 for (p = 0; p < 6; ++p) { 6780 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); 6781 } 6782 #endif 6783 } 6784 /* Split faces have 4 edges and the same cells as the parent */ 6785 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 6786 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 6787 for (f = fStart; f < fEnd; ++f) { 6788 for (r = 0; r < 4; ++r) { 6789 /* TODO: This can come from GetFaces_Internal() */ 6790 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}; 6791 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 6792 const PetscInt *cone, *ornt, *support; 6793 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 6794 6795 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 6796 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 6797 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 6798 orntNew[(r+3)%4] = ornt[(r+3)%4]; 6799 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 6800 orntNew[(r+0)%4] = ornt[r]; 6801 coneNew[(r+1)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 6802 orntNew[(r+1)%4] = 0; 6803 coneNew[(r+2)%4] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + (r+3)%4; 6804 orntNew[(r+2)%4] = -2; 6805 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6806 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6807 #if defined(PETSC_USE_DEBUG) 6808 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6809 for (p = 0; p < 4; ++p) { 6810 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); 6811 } 6812 #endif 6813 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 6814 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 6815 for (s = 0; s < supportSize; ++s) { 6816 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 6817 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 6818 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 6819 for (c = 0; c < coneSize; ++c) { 6820 if (cone[c] == f) break; 6821 } 6822 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+GetQuadSubfaceInverse_Static(ornt[c], r)]; 6823 } 6824 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 6825 #if defined(PETSC_USE_DEBUG) 6826 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6827 for (p = 0; p < supportSize; ++p) { 6828 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); 6829 } 6830 #endif 6831 } 6832 } 6833 /* Interior faces have 4 edges and 2 cells */ 6834 for (c = cStart; c < cEnd; ++c) { 6835 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}; 6836 const PetscInt *cone, *ornt; 6837 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 6838 6839 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 6840 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 6841 /* A-D face */ 6842 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 0; 6843 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 6844 orntNew[0] = 0; 6845 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6846 orntNew[1] = 0; 6847 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6848 orntNew[2] = -2; 6849 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 6850 orntNew[3] = -2; 6851 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6852 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6853 #if defined(PETSC_USE_DEBUG) 6854 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6855 for (p = 0; p < 4; ++p) { 6856 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); 6857 } 6858 #endif 6859 /* C-D face */ 6860 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 1; 6861 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 6862 orntNew[0] = 0; 6863 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6864 orntNew[1] = 0; 6865 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6866 orntNew[2] = -2; 6867 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 6868 orntNew[3] = -2; 6869 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6870 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6871 #if defined(PETSC_USE_DEBUG) 6872 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6873 for (p = 0; p < 4; ++p) { 6874 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); 6875 } 6876 #endif 6877 /* B-C face */ 6878 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 2; 6879 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 6880 orntNew[0] = -2; 6881 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 6882 orntNew[1] = 0; 6883 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6884 orntNew[2] = 0; 6885 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6886 orntNew[3] = -2; 6887 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6888 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6889 #if defined(PETSC_USE_DEBUG) 6890 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6891 for (p = 0; p < 4; ++p) { 6892 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); 6893 } 6894 #endif 6895 /* A-B face */ 6896 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 3; 6897 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 6898 orntNew[0] = -2; 6899 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 6900 orntNew[1] = 0; 6901 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6902 orntNew[2] = 0; 6903 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 0; 6904 orntNew[3] = -2; 6905 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6906 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6907 #if defined(PETSC_USE_DEBUG) 6908 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6909 for (p = 0; p < 4; ++p) { 6910 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); 6911 } 6912 #endif 6913 /* E-F face */ 6914 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 4; 6915 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6916 orntNew[0] = -2; 6917 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 6918 orntNew[1] = -2; 6919 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 6920 orntNew[2] = 0; 6921 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6922 orntNew[3] = 0; 6923 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6924 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6925 #if defined(PETSC_USE_DEBUG) 6926 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6927 for (p = 0; p < 4; ++p) { 6928 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); 6929 } 6930 #endif 6931 /* F-G face */ 6932 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 5; 6933 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 6934 orntNew[0] = -2; 6935 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 6936 orntNew[1] = -2; 6937 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 6938 orntNew[2] = 0; 6939 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6940 orntNew[3] = 0; 6941 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6942 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6943 #if defined(PETSC_USE_DEBUG) 6944 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6945 for (p = 0; p < 4; ++p) { 6946 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); 6947 } 6948 #endif 6949 /* G-H face */ 6950 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 6; 6951 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 6952 orntNew[0] = -2; 6953 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 6954 orntNew[1] = 0; 6955 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6956 orntNew[2] = 0; 6957 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 6958 orntNew[3] = -2; 6959 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6960 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6961 #if defined(PETSC_USE_DEBUG) 6962 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6963 for (p = 0; p < 4; ++p) { 6964 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); 6965 } 6966 #endif 6967 /* E-H face */ 6968 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 7; 6969 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6970 orntNew[0] = -2; 6971 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 6972 orntNew[1] = -2; 6973 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 6974 orntNew[2] = 0; 6975 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 1; 6976 orntNew[3] = 0; 6977 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6978 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6979 #if defined(PETSC_USE_DEBUG) 6980 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6981 for (p = 0; p < 4; ++p) { 6982 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); 6983 } 6984 #endif 6985 /* A-E face */ 6986 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 8; 6987 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 6988 orntNew[0] = 0; 6989 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 6990 orntNew[1] = 0; 6991 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 6992 orntNew[2] = -2; 6993 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 6994 orntNew[3] = -2; 6995 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 6996 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 6997 #if defined(PETSC_USE_DEBUG) 6998 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 6999 for (p = 0; p < 4; ++p) { 7000 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); 7001 } 7002 #endif 7003 /* D-F face */ 7004 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 9; 7005 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7006 orntNew[0] = -2; 7007 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7008 orntNew[1] = 0; 7009 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 7010 orntNew[2] = 0; 7011 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 2; 7012 orntNew[3] = -2; 7013 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7014 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7015 #if defined(PETSC_USE_DEBUG) 7016 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7017 for (p = 0; p < 4; ++p) { 7018 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); 7019 } 7020 #endif 7021 /* C-G face */ 7022 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 10; 7023 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 4; 7024 orntNew[0] = -2; 7025 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7026 orntNew[1] = -2; 7027 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7028 orntNew[2] = 0; 7029 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 7030 orntNew[3] = 0; 7031 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7032 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7033 #if defined(PETSC_USE_DEBUG) 7034 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7035 for (p = 0; p < 4; ++p) { 7036 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); 7037 } 7038 #endif 7039 /* B-H face */ 7040 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + 11; 7041 coneNew[0] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 5; 7042 orntNew[0] = 0; 7043 coneNew[1] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + 3; 7044 orntNew[1] = -2; 7045 coneNew[2] = eStartNew + (eEnd - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7046 orntNew[2] = -2; 7047 coneNew[3] = eStartNew + (eEnd - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7048 orntNew[3] = 0; 7049 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7050 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7051 #if defined(PETSC_USE_DEBUG) 7052 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7053 for (p = 0; p < 4; ++p) { 7054 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); 7055 } 7056 #endif 7057 for (r = 0; r < 12; ++r) { 7058 newp = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + r; 7059 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7060 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7061 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7062 #if defined(PETSC_USE_DEBUG) 7063 if ((newp < fStartNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fEndNew); 7064 for (p = 0; p < 2; ++p) { 7065 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); 7066 } 7067 #endif 7068 } 7069 } 7070 /* Split edges have 2 vertices and the same faces as the parent */ 7071 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7072 for (e = eStart; e < eEnd; ++e) { 7073 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7074 7075 for (r = 0; r < 2; ++r) { 7076 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7077 const PetscInt *cone, *ornt, *support; 7078 PetscInt coneNew[2], coneSize, c, supportSize, s; 7079 7080 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7081 coneNew[0] = vStartNew + (cone[0] - vStart); 7082 coneNew[1] = vStartNew + (cone[1] - vStart); 7083 coneNew[(r+1)%2] = newv; 7084 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7085 #if defined(PETSC_USE_DEBUG) 7086 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7087 for (p = 0; p < 2; ++p) { 7088 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); 7089 } 7090 #endif 7091 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7092 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7093 for (s = 0; s < supportSize; ++s) { 7094 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7095 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7096 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7097 for (c = 0; c < coneSize; ++c) { 7098 if (cone[c] == e) break; 7099 } 7100 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (ornt[c] < 0 ? (c+1-r)%4 : (c+r)%4); 7101 } 7102 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7103 #if defined(PETSC_USE_DEBUG) 7104 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7105 for (p = 0; p < supportSize; ++p) { 7106 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); 7107 } 7108 #endif 7109 } 7110 } 7111 /* Face edges have 2 vertices and 2+cells faces */ 7112 for (f = fStart; f < fEnd; ++f) { 7113 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}; 7114 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7115 const PetscInt *cone, *coneCell, *orntCell, *support; 7116 PetscInt coneNew[2], coneSize, c, supportSize, s; 7117 7118 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7119 for (r = 0; r < 4; ++r) { 7120 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7121 7122 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7123 coneNew[1] = newv; 7124 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7125 #if defined(PETSC_USE_DEBUG) 7126 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7127 for (p = 0; p < 2; ++p) { 7128 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); 7129 } 7130 #endif 7131 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7132 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7133 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7134 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7135 for (s = 0; s < supportSize; ++s) { 7136 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7137 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7138 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7139 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7140 supportRef[2+s] = fStartNew + (fEnd - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7141 } 7142 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7143 #if defined(PETSC_USE_DEBUG) 7144 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7145 for (p = 0; p < 2+supportSize; ++p) { 7146 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); 7147 } 7148 #endif 7149 } 7150 } 7151 /* Cell edges have 2 vertices and 4 faces */ 7152 for (c = cStart; c < cEnd; ++c) { 7153 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}; 7154 const PetscInt newv = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7155 const PetscInt *cone; 7156 PetscInt coneNew[2], supportNew[4]; 7157 7158 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7159 for (r = 0; r < 6; ++r) { 7160 const PetscInt newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7161 7162 coneNew[0] = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (cone[r] - fStart); 7163 coneNew[1] = newv; 7164 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7165 #if defined(PETSC_USE_DEBUG) 7166 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7167 for (p = 0; p < 2; ++p) { 7168 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); 7169 } 7170 #endif 7171 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fEnd - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 7172 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7173 #if defined(PETSC_USE_DEBUG) 7174 if ((newp < eStartNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eEndNew); 7175 for (p = 0; p < 4; ++p) { 7176 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); 7177 } 7178 #endif 7179 } 7180 } 7181 /* Old vertices have identical supports */ 7182 for (v = vStart; v < vEnd; ++v) { 7183 const PetscInt newp = vStartNew + (v - vStart); 7184 const PetscInt *support, *cone; 7185 PetscInt size, s; 7186 7187 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 7188 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 7189 for (s = 0; s < size; ++s) { 7190 PetscInt r = 0; 7191 7192 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7193 if (cone[1] == v) r = 1; 7194 supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 7195 } 7196 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7197 #if defined(PETSC_USE_DEBUG) 7198 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7199 for (p = 0; p < size; ++p) { 7200 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); 7201 } 7202 #endif 7203 } 7204 /* Edge vertices have 2 + faces supports */ 7205 for (e = eStart; e < eEnd; ++e) { 7206 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 7207 const PetscInt *cone, *support; 7208 PetscInt size, s; 7209 7210 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 7211 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7212 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 7213 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 7214 for (s = 0; s < size; ++s) { 7215 PetscInt r; 7216 7217 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7218 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 7219 supportRef[2+s] = eStartNew + (eEnd - eStart)*2 + (support[s] - fStart)*4 + r; 7220 } 7221 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7222 #if defined(PETSC_USE_DEBUG) 7223 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7224 for (p = 0; p < 2+size; ++p) { 7225 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); 7226 } 7227 #endif 7228 } 7229 /* Face vertices have 4 + cells supports */ 7230 for (f = fStart; f < fEnd; ++f) { 7231 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (f - fStart); 7232 const PetscInt *cone, *support; 7233 PetscInt size, s; 7234 7235 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7236 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7237 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eEnd - eStart)*2 + (f - fStart)*4 + r; 7238 for (s = 0; s < size; ++s) { 7239 PetscInt r; 7240 7241 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7242 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 7243 supportRef[4+s] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (support[s] - cStart)*6 + r; 7244 } 7245 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7246 #if defined(PETSC_USE_DEBUG) 7247 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 7248 for (p = 0; p < 4+size; ++p) { 7249 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); 7250 } 7251 #endif 7252 } 7253 /* Cell vertices have 6 supports */ 7254 for (c = cStart; c < cEnd; ++c) { 7255 const PetscInt newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (c - cStart); 7256 PetscInt supportNew[6]; 7257 7258 for (r = 0; r < 6; ++r) { 7259 supportNew[r] = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (c - cStart)*6 + r; 7260 } 7261 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7262 } 7263 ierr = PetscFree(supportRef);CHKERRQ(ierr); 7264 break; 7265 case REFINER_HYBRID_HEX_3D: 7266 ierr = DMPlexGetHybridBounds(rdm, &cMaxNew, &fMaxNew, &eMaxNew, NULL);CHKERRQ(ierr); 7267 /* 7268 Bottom (viewed from top) Top 7269 1---------2---------2 7---------2---------6 7270 | | | | | | 7271 | B 2 C | | H 2 G | 7272 | | | | | | 7273 3----3----0----1----1 3----3----0----1----1 7274 | | | | | | 7275 | A 0 D | | E 0 F | 7276 | | | | | | 7277 0---------0---------3 4---------0---------5 7278 */ 7279 /* Interior cells have 6 faces: Bottom, Top, Front, Back, Right, Left */ 7280 for (c = cStart; c < cMax; ++c) { 7281 const PetscInt newp = (c - cStart)*8; 7282 const PetscInt *cone, *ornt; 7283 PetscInt coneNew[6], orntNew[6]; 7284 7285 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7286 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7287 /* A hex */ 7288 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 0); 7289 orntNew[0] = ornt[0]; 7290 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7291 orntNew[1] = 0; 7292 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 0); 7293 orntNew[2] = ornt[2]; 7294 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7295 orntNew[3] = 0; 7296 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7297 orntNew[4] = 0; 7298 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 0); 7299 orntNew[5] = ornt[5]; 7300 ierr = DMPlexSetCone(rdm, newp+0, coneNew);CHKERRQ(ierr); 7301 ierr = DMPlexSetConeOrientation(rdm, newp+0, orntNew);CHKERRQ(ierr); 7302 #if defined(PETSC_USE_DEBUG) 7303 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); 7304 for (p = 0; p < 6; ++p) { 7305 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); 7306 } 7307 #endif 7308 /* B hex */ 7309 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 1); 7310 orntNew[0] = ornt[0]; 7311 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7312 orntNew[1] = 0; 7313 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; /* AB */ 7314 orntNew[2] = -1; 7315 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 1); 7316 orntNew[3] = ornt[3]; 7317 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7318 orntNew[4] = 0; 7319 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 3); 7320 orntNew[5] = ornt[5]; 7321 ierr = DMPlexSetCone(rdm, newp+1, coneNew);CHKERRQ(ierr); 7322 ierr = DMPlexSetConeOrientation(rdm, newp+1, orntNew);CHKERRQ(ierr); 7323 #if defined(PETSC_USE_DEBUG) 7324 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); 7325 for (p = 0; p < 6; ++p) { 7326 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); 7327 } 7328 #endif 7329 /* C hex */ 7330 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 2); 7331 orntNew[0] = ornt[0]; 7332 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7333 orntNew[1] = 0; 7334 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7335 orntNew[2] = -1; 7336 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 0); 7337 orntNew[3] = ornt[3]; 7338 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 1); 7339 orntNew[4] = ornt[4]; 7340 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; /* BC */ 7341 orntNew[5] = -4; 7342 ierr = DMPlexSetCone(rdm, newp+2, coneNew);CHKERRQ(ierr); 7343 ierr = DMPlexSetConeOrientation(rdm, newp+2, orntNew);CHKERRQ(ierr); 7344 #if defined(PETSC_USE_DEBUG) 7345 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); 7346 for (p = 0; p < 6; ++p) { 7347 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); 7348 } 7349 #endif 7350 /* D hex */ 7351 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], 3); 7352 orntNew[0] = ornt[0]; 7353 coneNew[1] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7354 orntNew[1] = 0; 7355 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 1); 7356 orntNew[2] = ornt[2]; 7357 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; /* CD */ 7358 orntNew[3] = 0; 7359 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 0); 7360 orntNew[4] = ornt[4]; 7361 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; /* AD */ 7362 orntNew[5] = -4; 7363 ierr = DMPlexSetCone(rdm, newp+3, coneNew);CHKERRQ(ierr); 7364 ierr = DMPlexSetConeOrientation(rdm, newp+3, orntNew);CHKERRQ(ierr); 7365 #if defined(PETSC_USE_DEBUG) 7366 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); 7367 for (p = 0; p < 6; ++p) { 7368 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); 7369 } 7370 #endif 7371 /* E hex */ 7372 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; /* AE */ 7373 orntNew[0] = -4; 7374 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 0); 7375 orntNew[1] = ornt[1]; 7376 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 3); 7377 orntNew[2] = ornt[2]; 7378 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7379 orntNew[3] = 0; 7380 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7381 orntNew[4] = -1; 7382 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 1); 7383 orntNew[5] = ornt[5]; 7384 ierr = DMPlexSetCone(rdm, newp+4, coneNew);CHKERRQ(ierr); 7385 ierr = DMPlexSetConeOrientation(rdm, newp+4, orntNew);CHKERRQ(ierr); 7386 #if defined(PETSC_USE_DEBUG) 7387 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); 7388 for (p = 0; p < 6; ++p) { 7389 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); 7390 } 7391 #endif 7392 /* F hex */ 7393 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; /* DF */ 7394 orntNew[0] = -4; 7395 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 1); 7396 orntNew[1] = ornt[1]; 7397 coneNew[2] = fStartNew + (cone[2] - fStart)*4 + GetQuadSubface_Static(ornt[2], 2); 7398 orntNew[2] = ornt[2]; 7399 coneNew[3] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7400 orntNew[3] = -1; 7401 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 3); 7402 orntNew[4] = ornt[4]; 7403 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; /* EF */ 7404 orntNew[5] = 1; 7405 ierr = DMPlexSetCone(rdm, newp+5, coneNew);CHKERRQ(ierr); 7406 ierr = DMPlexSetConeOrientation(rdm, newp+5, orntNew);CHKERRQ(ierr); 7407 #if defined(PETSC_USE_DEBUG) 7408 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); 7409 for (p = 0; p < 6; ++p) { 7410 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); 7411 } 7412 #endif 7413 /* G hex */ 7414 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; /* CG */ 7415 orntNew[0] = -4; 7416 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 2); 7417 orntNew[1] = ornt[1]; 7418 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; /* FG */ 7419 orntNew[2] = 0; 7420 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 3); 7421 orntNew[3] = ornt[3]; 7422 coneNew[4] = fStartNew + (cone[4] - fStart)*4 + GetQuadSubface_Static(ornt[4], 2); 7423 orntNew[4] = ornt[4]; 7424 coneNew[5] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7425 orntNew[5] = -3; 7426 ierr = DMPlexSetCone(rdm, newp+6, coneNew);CHKERRQ(ierr); 7427 ierr = DMPlexSetConeOrientation(rdm, newp+6, orntNew);CHKERRQ(ierr); 7428 #if defined(PETSC_USE_DEBUG) 7429 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); 7430 for (p = 0; p < 6; ++p) { 7431 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); 7432 } 7433 #endif 7434 /* H hex */ 7435 coneNew[0] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; /* BH */ 7436 orntNew[0] = -4; 7437 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], 3); 7438 orntNew[1] = ornt[1]; 7439 coneNew[2] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; /* EH */ 7440 orntNew[2] = -1; 7441 coneNew[3] = fStartNew + (cone[3] - fStart)*4 + GetQuadSubface_Static(ornt[3], 2); 7442 orntNew[3] = ornt[3]; 7443 coneNew[4] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; /* GH */ 7444 orntNew[4] = 3; 7445 coneNew[5] = fStartNew + (cone[5] - fStart)*4 + GetQuadSubface_Static(ornt[5], 2); 7446 orntNew[5] = ornt[5]; 7447 ierr = DMPlexSetCone(rdm, newp+7, coneNew);CHKERRQ(ierr); 7448 ierr = DMPlexSetConeOrientation(rdm, newp+7, orntNew);CHKERRQ(ierr); 7449 #if defined(PETSC_USE_DEBUG) 7450 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); 7451 for (p = 0; p < 6; ++p) { 7452 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); 7453 } 7454 #endif 7455 } 7456 /* Hybrid cells have 6 faces: Front, Back, Sides */ 7457 /* 7458 3---------2---------2 7459 | | | 7460 | D 2 C | 7461 | | | 7462 3----3----0----1----1 7463 | | | 7464 | A 0 B | 7465 | | | 7466 0---------0---------1 7467 */ 7468 for (c = cMax; c < cEnd; ++c) { 7469 const PetscInt newp = (cMax - cStart)*8 + (c - cMax)*4; 7470 const PetscInt *cone, *ornt, *fornt; 7471 PetscInt coneNew[6], orntNew[6], o, of, i; 7472 7473 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7474 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7475 ierr = DMPlexGetConeOrientation(dm, cone[0], &fornt);CHKERRQ(ierr); 7476 o = ornt[0] < 0 ? -1 : 1; 7477 for (r = 0; r < 4; ++r) { 7478 PetscInt subfA = GetQuadSubface_Static(ornt[0], r); 7479 PetscInt edgeA = GetQuadEdge_Static(ornt[0], r); 7480 PetscInt edgeB = GetQuadEdge_Static(ornt[0], (r+3)%4); 7481 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]); 7482 coneNew[0] = fStartNew + (cone[0] - fStart)*4 + subfA; 7483 orntNew[0] = ornt[0]; 7484 coneNew[1] = fStartNew + (cone[1] - fStart)*4 + subfA; 7485 orntNew[1] = ornt[0]; 7486 of = fornt[edgeA] < 0 ? -1 : 1; 7487 i = GetQuadEdgeInverse_Static(ornt[0], r) + 2; 7488 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeA] - fMax)*2 + (o*of < 0 ? 1 : 0); 7489 orntNew[i] = ornt[edgeA]; 7490 i = GetQuadEdgeInverse_Static(ornt[0], (r+1)%4) + 2; 7491 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeA; 7492 orntNew[i] = 0; 7493 i = GetQuadEdgeInverse_Static(ornt[0], (r+2)%4) + 2; 7494 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + edgeB; 7495 orntNew[i] = -2; 7496 of = fornt[edgeB] < 0 ? -1 : 1; 7497 i = GetQuadEdgeInverse_Static(ornt[0], (r+3)%4) + 2; 7498 coneNew[i] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (cone[2+edgeB] - fMax)*2 + (o*of < 0 ? 0 : 1); 7499 orntNew[i] = ornt[edgeB]; 7500 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7501 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7502 #if defined(PETSC_USE_DEBUG) 7503 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); 7504 for (p = 0; p < 2; ++p) { 7505 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); 7506 } 7507 for (p = 2; p < 6; ++p) { 7508 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); 7509 } 7510 #endif 7511 } 7512 } 7513 /* Interior split faces have 4 edges and the same cells as the parent */ 7514 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7515 ierr = PetscMalloc1(4 + maxSupportSize*2, &supportRef);CHKERRQ(ierr); 7516 for (f = fStart; f < fMax; ++f) { 7517 for (r = 0; r < 4; ++r) { 7518 /* TODO: This can come from GetFaces_Internal() */ 7519 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}; 7520 const PetscInt newp = fStartNew + (f - fStart)*4 + r; 7521 const PetscInt *cone, *ornt, *support; 7522 PetscInt coneNew[4], orntNew[4], coneSize, c, supportSize, s; 7523 7524 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7525 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7526 coneNew[(r+3)%4] = eStartNew + (cone[(r+3)%4] - eStart)*2 + (ornt[(r+3)%4] < 0 ? 0 : 1); 7527 orntNew[(r+3)%4] = ornt[(r+3)%4]; 7528 coneNew[(r+0)%4] = eStartNew + (cone[r] - eStart)*2 + (ornt[r] < 0 ? 1 : 0); 7529 orntNew[(r+0)%4] = ornt[r]; 7530 coneNew[(r+1)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7531 orntNew[(r+1)%4] = 0; 7532 coneNew[(r+2)%4] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + (r+3)%4; 7533 orntNew[(r+2)%4] = -2; 7534 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7535 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7536 #if defined(PETSC_USE_DEBUG) 7537 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7538 for (p = 0; p < 4; ++p) { 7539 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); 7540 } 7541 #endif 7542 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7543 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7544 for (s = 0; s < supportSize; ++s) { 7545 PetscInt subf; 7546 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7547 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7548 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7549 for (c = 0; c < coneSize; ++c) { 7550 if (cone[c] == f) break; 7551 } 7552 subf = GetQuadSubfaceInverse_Static(ornt[c], r); 7553 if (support[s] < cMax) { 7554 supportRef[s] = cStartNew + (support[s] - cStart)*8 + newCells[c*4+subf]; 7555 } else { 7556 supportRef[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + subf; 7557 } 7558 } 7559 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7560 #if defined(PETSC_USE_DEBUG) 7561 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7562 for (p = 0; p < supportSize; ++p) { 7563 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); 7564 } 7565 #endif 7566 } 7567 } 7568 /* Interior cell faces have 4 edges and 2 cells */ 7569 for (c = cStart; c < cMax; ++c) { 7570 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}; 7571 const PetscInt *cone, *ornt; 7572 PetscInt newp, coneNew[4], orntNew[4], supportNew[2]; 7573 7574 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7575 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7576 /* A-D face */ 7577 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 0; 7578 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 3); 7579 orntNew[0] = 0; 7580 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7581 orntNew[1] = 0; 7582 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7583 orntNew[2] = -2; 7584 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 0); 7585 orntNew[3] = -2; 7586 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7587 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7588 #if defined(PETSC_USE_DEBUG) 7589 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7590 for (p = 0; p < 4; ++p) { 7591 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); 7592 } 7593 #endif 7594 /* C-D face */ 7595 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 1; 7596 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 2); 7597 orntNew[0] = 0; 7598 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7599 orntNew[1] = 0; 7600 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7601 orntNew[2] = -2; 7602 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 0); 7603 orntNew[3] = -2; 7604 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7605 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7606 #if defined(PETSC_USE_DEBUG) 7607 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7608 for (p = 0; p < 4; ++p) { 7609 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); 7610 } 7611 #endif 7612 /* B-C face */ 7613 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 2; 7614 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 1); 7615 orntNew[0] = -2; 7616 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 0); 7617 orntNew[1] = 0; 7618 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7619 orntNew[2] = 0; 7620 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7621 orntNew[3] = -2; 7622 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7623 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7624 #if defined(PETSC_USE_DEBUG) 7625 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7626 for (p = 0; p < 4; ++p) { 7627 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); 7628 } 7629 #endif 7630 /* A-B face */ 7631 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 3; 7632 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadEdge_Static(ornt[0], 0); 7633 orntNew[0] = -2; 7634 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 3); 7635 orntNew[1] = 0; 7636 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7637 orntNew[2] = 0; 7638 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 0; 7639 orntNew[3] = -2; 7640 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7641 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7642 #if defined(PETSC_USE_DEBUG) 7643 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7644 for (p = 0; p < 4; ++p) { 7645 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); 7646 } 7647 #endif 7648 /* E-F face */ 7649 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 4; 7650 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7651 orntNew[0] = -2; 7652 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 2); 7653 orntNew[1] = -2; 7654 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 0); 7655 orntNew[2] = 0; 7656 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7657 orntNew[3] = 0; 7658 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7659 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7660 #if defined(PETSC_USE_DEBUG) 7661 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7662 for (p = 0; p < 4; ++p) { 7663 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); 7664 } 7665 #endif 7666 /* F-G face */ 7667 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 5; 7668 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7669 orntNew[0] = -2; 7670 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 2); 7671 orntNew[1] = -2; 7672 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 1); 7673 orntNew[2] = 0; 7674 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7675 orntNew[3] = 0; 7676 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7677 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7678 #if defined(PETSC_USE_DEBUG) 7679 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7680 for (p = 0; p < 4; ++p) { 7681 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); 7682 } 7683 #endif 7684 /* G-H face */ 7685 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 6; 7686 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 2); 7687 orntNew[0] = -2; 7688 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 2); 7689 orntNew[1] = 0; 7690 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7691 orntNew[2] = 0; 7692 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7693 orntNew[3] = -2; 7694 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7695 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7696 #if defined(PETSC_USE_DEBUG) 7697 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7698 for (p = 0; p < 4; ++p) { 7699 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); 7700 } 7701 #endif 7702 /* E-H face */ 7703 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 7; 7704 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7705 orntNew[0] = -2; 7706 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 1); 7707 orntNew[1] = -2; 7708 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadEdge_Static(ornt[1], 3); 7709 orntNew[2] = 0; 7710 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 1; 7711 orntNew[3] = 0; 7712 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7713 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7714 #if defined(PETSC_USE_DEBUG) 7715 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7716 for (p = 0; p < 4; ++p) { 7717 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); 7718 } 7719 #endif 7720 /* A-E face */ 7721 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 8; 7722 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 3); 7723 orntNew[0] = 0; 7724 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7725 orntNew[1] = 0; 7726 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7727 orntNew[2] = -2; 7728 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 0); 7729 orntNew[3] = -2; 7730 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7731 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7732 #if defined(PETSC_USE_DEBUG) 7733 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7734 for (p = 0; p < 4; ++p) { 7735 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); 7736 } 7737 #endif 7738 /* D-F face */ 7739 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 9; 7740 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[2] - fStart)*4 + GetQuadEdge_Static(ornt[2], 1); 7741 orntNew[0] = -2; 7742 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 3); 7743 orntNew[1] = 0; 7744 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7745 orntNew[2] = 0; 7746 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 2; 7747 orntNew[3] = -2; 7748 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7749 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7750 #if defined(PETSC_USE_DEBUG) 7751 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7752 for (p = 0; p < 4; ++p) { 7753 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); 7754 } 7755 #endif 7756 /* C-G face */ 7757 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 10; 7758 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 4; 7759 orntNew[0] = -2; 7760 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[4] - fStart)*4 + GetQuadEdge_Static(ornt[4], 1); 7761 orntNew[1] = -2; 7762 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 3); 7763 orntNew[2] = 0; 7764 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7765 orntNew[3] = 0; 7766 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7767 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7768 #if defined(PETSC_USE_DEBUG) 7769 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7770 for (p = 0; p < 4; ++p) { 7771 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); 7772 } 7773 #endif 7774 /* B-H face */ 7775 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + 11; 7776 coneNew[0] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 5; 7777 orntNew[0] = 0; 7778 coneNew[1] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + 3; 7779 orntNew[1] = -2; 7780 coneNew[2] = eStartNew + (eMax - eStart)*2 + (cone[3] - fStart)*4 + GetQuadEdge_Static(ornt[3], 1); 7781 orntNew[2] = -2; 7782 coneNew[3] = eStartNew + (eMax - eStart)*2 + (cone[5] - fStart)*4 + GetQuadEdge_Static(ornt[5], 2); 7783 orntNew[3] = 0; 7784 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7785 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7786 #if defined(PETSC_USE_DEBUG) 7787 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7788 for (p = 0; p < 4; ++p) { 7789 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); 7790 } 7791 #endif 7792 for (r = 0; r < 12; ++r) { 7793 newp = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + r; 7794 supportNew[0] = cStartNew + (c - cStart)*8 + newCells[r*2+0]; 7795 supportNew[1] = cStartNew + (c - cStart)*8 + newCells[r*2+1]; 7796 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7797 #if defined(PETSC_USE_DEBUG) 7798 if ((newp < fStartNew) || (newp >= fMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a face [%D, %D)", newp, fStartNew, fMaxNew); 7799 for (p = 0; p < 2; ++p) { 7800 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); 7801 } 7802 #endif 7803 } 7804 } 7805 /* Hybrid split faces have 4 edges and same cells */ 7806 for (f = fMax; f < fEnd; ++f) { 7807 const PetscInt *cone, *ornt, *support; 7808 PetscInt coneNew[4], orntNew[4]; 7809 PetscInt supportNew[2], size, s, c; 7810 7811 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7812 ierr = DMPlexGetConeOrientation(dm, f, &ornt);CHKERRQ(ierr); 7813 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 7814 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7815 for (r = 0; r < 2; ++r) { 7816 const PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + r; 7817 7818 coneNew[0] = eStartNew + (cone[0] - eStart)*2 + (ornt[0] < 0 ? 1-r : r); 7819 orntNew[0] = ornt[0]; 7820 coneNew[1] = eStartNew + (cone[1] - eStart)*2 + (ornt[1] < 0 ? 1-r : r); 7821 orntNew[1] = ornt[1]; 7822 coneNew[2+r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (cone[2+r] - eMax); 7823 orntNew[2+r] = 0; 7824 coneNew[3-r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 7825 orntNew[3-r] = 0; 7826 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7827 ierr = DMPlexSetConeOrientation(rdm, newp, orntNew);CHKERRQ(ierr); 7828 #if defined(PETSC_USE_DEBUG) 7829 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7830 for (p = 0; p < 2; ++p) { 7831 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); 7832 } 7833 for (p = 2; p < 4; ++p) { 7834 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); 7835 } 7836 #endif 7837 for (s = 0; s < size; ++s) { 7838 const PetscInt *coneCell, *orntCell, *fornt; 7839 PetscInt o, of; 7840 7841 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7842 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7843 o = orntCell[0] < 0 ? -1 : 1; 7844 for (c = 2; c < 6; ++c) if (coneCell[c] == f) break; 7845 if (c >= 6) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Could not find face %D in cone of cell %D", f, support[s]); 7846 ierr = DMPlexGetConeOrientation(dm, coneCell[0], &fornt);CHKERRQ(ierr); 7847 of = fornt[c-2] < 0 ? -1 : 1; 7848 supportNew[s] = cStartNew + (cMax - cStart)*8 + (support[s] - cMax)*4 + (GetQuadEdgeInverse_Static(orntCell[0], c-2) + (o*of < 0 ? 1-r : r))%4; 7849 } 7850 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 7851 #if defined(PETSC_USE_DEBUG) 7852 if ((newp < fMaxNew) || (newp >= fEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid face [%D, %D)", newp, fMaxNew, fEndNew); 7853 for (p = 0; p < size; ++p) { 7854 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); 7855 } 7856 #endif 7857 } 7858 } 7859 /* Hybrid cell faces have 4 edges and 2 cells */ 7860 for (c = cMax; c < cEnd; ++c) { 7861 PetscInt newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4; 7862 const PetscInt *cone, *ornt; 7863 PetscInt coneNew[4], orntNew[4]; 7864 PetscInt supportNew[2]; 7865 7866 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 7867 ierr = DMPlexGetConeOrientation(dm, c, &ornt);CHKERRQ(ierr); 7868 for (r = 0; r < 4; ++r) { 7869 #if 0 7870 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + GetQuadSubface_Static(ornt[0], r); 7871 orntNew[0] = 0; 7872 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + GetQuadSubface_Static(ornt[1], r); 7873 orntNew[1] = 0; 7874 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+GetQuadEdge_Static(ornt[0], r)] - fMax); 7875 orntNew[2] = 0; 7876 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7877 orntNew[3] = 0; 7878 #else 7879 coneNew[0] = eStartNew + (eMax - eStart)*2 + (cone[0] - fStart)*4 + r; 7880 orntNew[0] = 0; 7881 coneNew[1] = eStartNew + (eMax - eStart)*2 + (cone[1] - fStart)*4 + r; 7882 orntNew[1] = 0; 7883 coneNew[2] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (cone[2+r] - fMax); 7884 orntNew[2] = 0; 7885 coneNew[3] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 7886 orntNew[3] = 0; 7887 #endif 7888 ierr = DMPlexSetCone(rdm, newp+r, coneNew);CHKERRQ(ierr); 7889 ierr = DMPlexSetConeOrientation(rdm, newp+r, orntNew);CHKERRQ(ierr); 7890 #if defined(PETSC_USE_DEBUG) 7891 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); 7892 for (p = 0; p < 2; ++p) { 7893 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); 7894 } 7895 for (p = 2; p < 4; ++p) { 7896 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); 7897 } 7898 #endif 7899 supportNew[0] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], r); 7900 supportNew[1] = cStartNew + (cMax - cStart)*8 + (c - cMax)*4 + GetQuadSubface_Static(ornt[0], (r+1)%4); 7901 ierr = DMPlexSetSupport(rdm, newp+r, supportNew);CHKERRQ(ierr); 7902 #if defined(PETSC_USE_DEBUG) 7903 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); 7904 for (p = 0; p < 2; ++p) { 7905 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); 7906 } 7907 #endif 7908 } 7909 } 7910 /* Interior split edges have 2 vertices and the same faces as the parent */ 7911 ierr = DMPlexGetMaxSizes(dm, NULL, &maxSupportSize);CHKERRQ(ierr); 7912 for (e = eStart; e < eMax; ++e) { 7913 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 7914 7915 for (r = 0; r < 2; ++r) { 7916 const PetscInt newp = eStartNew + (e - eStart)*2 + r; 7917 const PetscInt *cone, *ornt, *support; 7918 PetscInt coneNew[2], coneSize, c, supportSize, s; 7919 7920 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 7921 coneNew[0] = vStartNew + (cone[0] - vStart); 7922 coneNew[1] = vStartNew + (cone[1] - vStart); 7923 coneNew[(r+1)%2] = newv; 7924 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7925 #if defined(PETSC_USE_DEBUG) 7926 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7927 for (p = 0; p < 2; ++p) { 7928 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); 7929 } 7930 #endif 7931 ierr = DMPlexGetSupportSize(dm, e, &supportSize);CHKERRQ(ierr); 7932 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 7933 for (s = 0; s < supportSize; ++s) { 7934 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7935 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 7936 ierr = DMPlexGetConeOrientation(dm, support[s], &ornt);CHKERRQ(ierr); 7937 for (c = 0; c < coneSize; ++c) { 7938 if (cone[c] == e) break; 7939 } 7940 if (support[s] < fMax) { 7941 supportRef[s] = fStartNew + (support[s] - fStart)*4 + (c + (ornt[c] < 0 ? 1-r : r))%4; 7942 } else { 7943 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + (ornt[c] < 0 ? 1-r : r); 7944 } 7945 } 7946 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7947 #if defined(PETSC_USE_DEBUG) 7948 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7949 for (p = 0; p < supportSize; ++p) { 7950 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); 7951 } 7952 #endif 7953 } 7954 } 7955 /* Interior face edges have 2 vertices and 2+cells faces */ 7956 for (f = fStart; f < fMax; ++f) { 7957 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}; 7958 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 7959 const PetscInt *cone, *coneCell, *orntCell, *support; 7960 PetscInt coneNew[2], coneSize, c, supportSize, s; 7961 7962 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 7963 for (r = 0; r < 4; ++r) { 7964 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 7965 7966 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[r] - eStart); 7967 coneNew[1] = newv; 7968 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 7969 #if defined(PETSC_USE_DEBUG) 7970 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7971 for (p = 0; p < 2; ++p) { 7972 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); 7973 } 7974 #endif 7975 ierr = DMPlexGetSupportSize(dm, f, &supportSize);CHKERRQ(ierr); 7976 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 7977 supportRef[0] = fStartNew + (f - fStart)*4 + r; 7978 supportRef[1] = fStartNew + (f - fStart)*4 + (r+1)%4; 7979 for (s = 0; s < supportSize; ++s) { 7980 ierr = DMPlexGetConeSize(dm, support[s], &coneSize);CHKERRQ(ierr); 7981 ierr = DMPlexGetCone(dm, support[s], &coneCell);CHKERRQ(ierr); 7982 ierr = DMPlexGetConeOrientation(dm, support[s], &orntCell);CHKERRQ(ierr); 7983 for (c = 0; c < coneSize; ++c) if (coneCell[c] == f) break; 7984 if (support[s] < cMax) { 7985 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (support[s] - cStart)*12 + newFaces[c*4 + GetQuadEdgeInverse_Static(orntCell[c], r)]; 7986 } else { 7987 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + r; 7988 } 7989 } 7990 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 7991 #if defined(PETSC_USE_DEBUG) 7992 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 7993 for (p = 0; p < 2+supportSize; ++p) { 7994 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); 7995 } 7996 #endif 7997 } 7998 } 7999 /* Interior cell edges have 2 vertices and 4 faces */ 8000 for (c = cStart; c < cMax; ++c) { 8001 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}; 8002 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 8003 const PetscInt *cone; 8004 PetscInt coneNew[2], supportNew[4]; 8005 8006 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8007 for (r = 0; r < 6; ++r) { 8008 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8009 8010 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[r] - fStart); 8011 coneNew[1] = newv; 8012 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8013 #if defined(PETSC_USE_DEBUG) 8014 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 8015 for (p = 0; p < 2; ++p) { 8016 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); 8017 } 8018 #endif 8019 for (f = 0; f < 4; ++f) supportNew[f] = fStartNew + (fMax - fStart)*4 + (c - cStart)*12 + newFaces[r*4+f]; 8020 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8021 #if defined(PETSC_USE_DEBUG) 8022 if ((newp < eStartNew) || (newp >= eMaxNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not an edge [%D, %D)", newp, eStartNew, eMaxNew); 8023 for (p = 0; p < 4; ++p) { 8024 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); 8025 } 8026 #endif 8027 } 8028 } 8029 /* Hybrid edges have two vertices and the same faces */ 8030 for (e = eMax; e < eEnd; ++e) { 8031 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (e - eMax); 8032 const PetscInt *cone, *support, *fcone; 8033 PetscInt coneNew[2], size, fsize, s; 8034 8035 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8036 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8037 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8038 coneNew[0] = vStartNew + (cone[0] - vStart); 8039 coneNew[1] = vStartNew + (cone[1] - vStart); 8040 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8041 #if defined(PETSC_USE_DEBUG) 8042 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8043 for (p = 0; p < 2; ++p) { 8044 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); 8045 } 8046 #endif 8047 for (s = 0; s < size; ++s) { 8048 ierr = DMPlexGetConeSize(dm, support[s], &fsize);CHKERRQ(ierr); 8049 ierr = DMPlexGetCone(dm, support[s], &fcone);CHKERRQ(ierr); 8050 for (c = 0; c < fsize; ++c) if (fcone[c] == e) break; 8051 if ((c < 2) || (c > 3)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Edge %D not found in cone of face %D", e, support[s]); 8052 supportRef[s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (support[s] - fMax)*2 + c-2; 8053 } 8054 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8055 #if defined(PETSC_USE_DEBUG) 8056 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8057 for (p = 0; p < size; ++p) { 8058 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); 8059 } 8060 #endif 8061 } 8062 /* Hybrid face edges have 2 vertices and 2+cells faces */ 8063 for (f = fMax; f < fEnd; ++f) { 8064 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (f - fMax); 8065 const PetscInt *cone, *support, *ccone, *cornt; 8066 PetscInt coneNew[2], size, csize, s; 8067 8068 ierr = DMPlexGetCone(dm, f, &cone);CHKERRQ(ierr); 8069 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8070 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8071 coneNew[0] = vStartNew + (vEnd - vStart) + (cone[0] - eStart); 8072 coneNew[1] = vStartNew + (vEnd - vStart) + (cone[1] - eStart); 8073 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8074 #if defined(PETSC_USE_DEBUG) 8075 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8076 for (p = 0; p < 2; ++p) { 8077 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); 8078 } 8079 #endif 8080 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 0; 8081 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (f - fMax)*2 + 1; 8082 for (s = 0; s < size; ++s) { 8083 ierr = DMPlexGetConeSize(dm, support[s], &csize);CHKERRQ(ierr); 8084 ierr = DMPlexGetCone(dm, support[s], &ccone);CHKERRQ(ierr); 8085 ierr = DMPlexGetConeOrientation(dm, support[s], &cornt);CHKERRQ(ierr); 8086 for (c = 0; c < csize; ++c) if (ccone[c] == f) break; 8087 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]); 8088 supportRef[2+s] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (support[s] - cMax)*4 + c-2; 8089 } 8090 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8091 #if defined(PETSC_USE_DEBUG) 8092 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8093 for (p = 0; p < 2+size; ++p) { 8094 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); 8095 } 8096 #endif 8097 } 8098 /* Hybrid cell edges have 2 vertices and 4 faces */ 8099 for (c = cMax; c < cEnd; ++c) { 8100 const PetscInt newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (c - cMax); 8101 const PetscInt *cone, *support; 8102 PetscInt coneNew[2], size; 8103 8104 ierr = DMPlexGetCone(dm, c, &cone);CHKERRQ(ierr); 8105 ierr = DMPlexGetSupportSize(dm, c, &size);CHKERRQ(ierr); 8106 ierr = DMPlexGetSupport(dm, c, &support);CHKERRQ(ierr); 8107 coneNew[0] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[0] - fStart); 8108 coneNew[1] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (cone[1] - fStart); 8109 ierr = DMPlexSetCone(rdm, newp, coneNew);CHKERRQ(ierr); 8110 #if defined(PETSC_USE_DEBUG) 8111 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8112 for (p = 0; p < 2; ++p) { 8113 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); 8114 } 8115 #endif 8116 supportRef[0] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 0; 8117 supportRef[1] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 1; 8118 supportRef[2] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 2; 8119 supportRef[3] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (c - cMax)*4 + 3; 8120 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8121 #if defined(PETSC_USE_DEBUG) 8122 if ((newp < eMaxNew) || (newp >= eEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a hybrid edge [%D, %D)", newp, eMaxNew, eEndNew); 8123 for (p = 0; p < 4; ++p) { 8124 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); 8125 } 8126 #endif 8127 } 8128 /* Interior vertices have identical supports */ 8129 for (v = vStart; v < vEnd; ++v) { 8130 const PetscInt newp = vStartNew + (v - vStart); 8131 const PetscInt *support, *cone; 8132 PetscInt size, s; 8133 8134 ierr = DMPlexGetSupportSize(dm, v, &size);CHKERRQ(ierr); 8135 ierr = DMPlexGetSupport(dm, v, &support);CHKERRQ(ierr); 8136 for (s = 0; s < size; ++s) { 8137 PetscInt r = 0; 8138 8139 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8140 if (cone[1] == v) r = 1; 8141 if (support[s] < eMax) supportRef[s] = eStartNew + (support[s] - eStart)*2 + r; 8142 else supportRef[s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (support[s] - eMax); 8143 } 8144 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8145 #if defined(PETSC_USE_DEBUG) 8146 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8147 for (p = 0; p < size; ++p) { 8148 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); 8149 } 8150 #endif 8151 } 8152 /* Interior edge vertices have 2 + faces supports */ 8153 for (e = eStart; e < eMax; ++e) { 8154 const PetscInt newp = vStartNew + (vEnd - vStart) + (e - eStart); 8155 const PetscInt *cone, *support; 8156 PetscInt size, s; 8157 8158 ierr = DMPlexGetSupportSize(dm, e, &size);CHKERRQ(ierr); 8159 ierr = DMPlexGetSupport(dm, e, &support);CHKERRQ(ierr); 8160 supportRef[0] = eStartNew + (e - eStart)*2 + 0; 8161 supportRef[1] = eStartNew + (e - eStart)*2 + 1; 8162 for (s = 0; s < size; ++s) { 8163 PetscInt r; 8164 8165 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8166 for (r = 0; r < 4; ++r) if (cone[r] == e) break; 8167 if (support[s] < fMax) { 8168 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (support[s] - fStart)*4 + r; 8169 } else { 8170 supportRef[2+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (support[s] - fMax); 8171 } 8172 } 8173 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8174 #if defined(PETSC_USE_DEBUG) 8175 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8176 for (p = 0; p < 2+size; ++p) { 8177 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); 8178 } 8179 #endif 8180 } 8181 /* Interior face vertices have 4 + cells supports */ 8182 for (f = fStart; f < fMax; ++f) { 8183 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8184 const PetscInt *cone, *support; 8185 PetscInt size, s; 8186 8187 ierr = DMPlexGetSupportSize(dm, f, &size);CHKERRQ(ierr); 8188 ierr = DMPlexGetSupport(dm, f, &support);CHKERRQ(ierr); 8189 for (r = 0; r < 4; ++r) supportRef[r] = eStartNew + (eMax - eStart)*2 + (f - fStart)*4 + r; 8190 for (s = 0; s < size; ++s) { 8191 PetscInt r; 8192 8193 ierr = DMPlexGetCone(dm, support[s], &cone);CHKERRQ(ierr); 8194 for (r = 0; r < 6; ++r) if (cone[r] == f) break; 8195 if (support[s] < cMax) { 8196 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (support[s] - cStart)*6 + r; 8197 } else { 8198 supportRef[4+s] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (support[s] - cMax); 8199 } 8200 } 8201 ierr = DMPlexSetSupport(rdm, newp, supportRef);CHKERRQ(ierr); 8202 #if defined(PETSC_USE_DEBUG) 8203 if ((newp < vStartNew) || (newp >= vEndNew)) SETERRQ3(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Point %D is not a vertex [%D, %D)", newp, vStartNew, vEndNew); 8204 for (p = 0; p < 4+size; ++p) { 8205 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); 8206 } 8207 #endif 8208 } 8209 /* Cell vertices have 6 supports */ 8210 for (c = cStart; c < cMax; ++c) { 8211 const PetscInt newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (c - cStart); 8212 PetscInt supportNew[6]; 8213 8214 for (r = 0; r < 6; ++r) { 8215 supportNew[r] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (c - cStart)*6 + r; 8216 } 8217 ierr = DMPlexSetSupport(rdm, newp, supportNew);CHKERRQ(ierr); 8218 } 8219 ierr = PetscFree(supportRef);CHKERRQ(ierr); 8220 break; 8221 default: 8222 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8223 } 8224 PetscFunctionReturn(0); 8225 } 8226 8227 static PetscErrorCode CellRefinerSetCoordinates(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8228 { 8229 PetscSection coordSection, coordSectionNew; 8230 Vec coordinates, coordinatesNew; 8231 PetscScalar *coords, *coordsNew; 8232 const PetscInt numVertices = depthSize ? depthSize[0] : 0; 8233 PetscInt dim, spaceDim, depth, bs, coordSizeNew, cStart, cEnd, cMax; 8234 PetscInt c, vStart, vStartNew, vEnd, v, eStart, eEnd, eMax, e, fStart, fEnd, fMax, f; 8235 PetscInt cStartNew, cEndNew, vEndNew, *parentId = NULL; 8236 VecType vtype; 8237 PetscBool isperiodic, localize = PETSC_FALSE, needcoords = PETSC_FALSE; 8238 const PetscReal *maxCell, *L; 8239 const DMBoundaryType *bd; 8240 PetscErrorCode ierr; 8241 8242 PetscFunctionBegin; 8243 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 8244 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 8245 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8246 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8247 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8248 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8249 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, NULL);CHKERRQ(ierr); 8250 if (cMax < 0) cMax = cEnd; 8251 if (fMax < 0) fMax = fEnd; 8252 if (eMax < 0) eMax = eEnd; 8253 ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, NULL, NULL, &vStartNew);CHKERRQ(ierr); 8254 ierr = GetDepthEnd_Private(depth, depthSize, &cEndNew, NULL, NULL, &vEndNew);CHKERRQ(ierr); 8255 ierr = DMGetPeriodicity(dm, &isperiodic, &maxCell, &L, &bd);CHKERRQ(ierr); 8256 /* Determine if we need to localize coordinates when generating them */ 8257 if (isperiodic && !maxCell) { 8258 ierr = DMGetCoordinatesLocalized(dm, &localize);CHKERRQ(ierr); 8259 if (!localize) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot refine if coordinates have not been localized"); 8260 } 8261 if (isperiodic) { 8262 ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)dm),((PetscObject)dm)->prefix,"DMPlex coords refinement options","DM");CHKERRQ(ierr); 8263 ierr = PetscOptionsBool("-dm_plex_refine_localize","Automatically localize from parent cells",NULL,localize,&localize,NULL);CHKERRQ(ierr); 8264 ierr = PetscOptionsEnd();CHKERRQ(ierr); 8265 if (localize) { 8266 ierr = DMLocalizeCoordinates(dm);CHKERRQ(ierr); 8267 } 8268 } 8269 ierr = DMSetPeriodicity(rdm, isperiodic, maxCell, L, bd);CHKERRQ(ierr); 8270 8271 ierr = DMGetCoordinateSection(dm, &coordSection);CHKERRQ(ierr); 8272 ierr = PetscSectionGetFieldComponents(coordSection, 0, &spaceDim);CHKERRQ(ierr); 8273 ierr = PetscSectionCreate(PetscObjectComm((PetscObject)dm), &coordSectionNew);CHKERRQ(ierr); 8274 ierr = PetscSectionSetNumFields(coordSectionNew, 1);CHKERRQ(ierr); 8275 ierr = PetscSectionSetFieldComponents(coordSectionNew, 0, spaceDim);CHKERRQ(ierr); 8276 8277 if (localize) { 8278 PetscInt p, r, newp, *pi; 8279 8280 /* New coordinates will be already localized on the cell */ 8281 ierr = PetscSectionSetChart(coordSectionNew, 0, vStartNew+numVertices);CHKERRQ(ierr); 8282 8283 /* We need the parentId to properly localize coordinates */ 8284 ierr = PetscMalloc1(cEndNew-cStartNew,&pi);CHKERRQ(ierr); 8285 switch (refiner) { 8286 case REFINER_NOOP: 8287 break; 8288 case REFINER_SIMPLEX_1D: 8289 for (p = cStart; p < cEnd; ++p) { 8290 for (r = 0; r < 2; ++r) { 8291 newp = (p - cStart)*2 + r; 8292 pi[newp] = p; 8293 } 8294 } 8295 break; 8296 case REFINER_SIMPLEX_2D: 8297 for (p = cStart; p < cEnd; ++p) { 8298 for (r = 0; r < 4; ++r) { 8299 newp = (p - cStart)*4 + r; 8300 pi[newp] = p; 8301 } 8302 } 8303 break; 8304 case REFINER_HEX_2D: 8305 for (p = cStart; p < cEnd; ++p) { 8306 for (r = 0; r < 4; ++r) { 8307 newp = (p - cStart)*4 + r; 8308 pi[newp] = p; 8309 } 8310 } 8311 break; 8312 case REFINER_SIMPLEX_TO_HEX_2D: 8313 for (p = cStart; p < cEnd; ++p) { 8314 for (r = 0; r < 3; ++r) { 8315 newp = (p - cStart)*3 + r; 8316 pi[newp] = p; 8317 } 8318 } 8319 break; 8320 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8321 for (p = cStart; p < cMax; ++p) { 8322 for (r = 0; r < 3; ++r) { 8323 newp = (p - cStart)*3 + r; 8324 pi[newp] = p; 8325 } 8326 } 8327 for (p = cMax; p < cEnd; ++p) { 8328 for (r = 0; r < 4; ++r) { 8329 newp = (cMax - cStart)*3 + (p - cMax)*4 + r; 8330 pi[newp] = p; 8331 } 8332 } 8333 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8334 cMax = cEnd; 8335 eMax = eEnd; 8336 break; 8337 case REFINER_HYBRID_SIMPLEX_2D: 8338 for (p = cStart; p < cMax; ++p) { 8339 for (r = 0; r < 4; ++r) { 8340 newp = (p - cStart)*4 + r; 8341 pi[newp] = p; 8342 } 8343 } 8344 for (p = cMax; p < cEnd; ++p) { 8345 for (r = 0; r < 2; ++r) { 8346 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8347 pi[newp] = p; 8348 } 8349 } 8350 break; 8351 case REFINER_HYBRID_HEX_2D: 8352 for (p = cStart; p < cMax; ++p) { 8353 for (r = 0; r < 4; ++r) { 8354 newp = (p - cStart)*4 + r; 8355 pi[newp] = p; 8356 } 8357 } 8358 for (p = cMax; p < cEnd; ++p) { 8359 for (r = 0; r < 2; ++r) { 8360 newp = (cMax - cStart)*4 + (p - cMax)*2 + r; 8361 pi[newp] = p; 8362 } 8363 } 8364 break; 8365 case REFINER_SIMPLEX_3D: 8366 for (p = cStart; p < cEnd; ++p) { 8367 for (r = 0; r < 8; ++r) { 8368 newp = (p - cStart)*8 + r; 8369 pi[newp] = p; 8370 } 8371 } 8372 break; 8373 case REFINER_HYBRID_SIMPLEX_3D: 8374 for (p = cStart; p < cMax; ++p) { 8375 for (r = 0; r < 8; ++r) { 8376 newp = (p - cStart)*8 + r; 8377 pi[newp] = p; 8378 } 8379 } 8380 for (p = cMax; p < cEnd; ++p) { 8381 for (r = 0; r < 4; ++r) { 8382 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8383 pi[newp] = p; 8384 } 8385 } 8386 break; 8387 case REFINER_SIMPLEX_TO_HEX_3D: 8388 for (p = cStart; p < cEnd; ++p) { 8389 for (r = 0; r < 4; ++r) { 8390 newp = (p - cStart)*4 + r; 8391 pi[newp] = p; 8392 } 8393 } 8394 break; 8395 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8396 for (p = cStart; p < cMax; ++p) { 8397 for (r = 0; r < 4; ++r) { 8398 newp = (p - cStart)*4 + r; 8399 pi[newp] = p; 8400 } 8401 } 8402 for (p = cMax; p < cEnd; ++p) { 8403 for (r = 0; r < 3; ++r) { 8404 newp = (cMax - cStart)*4 + (p - cMax)*3 + r; 8405 pi[newp] = p; 8406 } 8407 } 8408 break; 8409 case REFINER_HEX_3D: 8410 for (p = cStart; p < cEnd; ++p) { 8411 for (r = 0; r < 8; ++r) { 8412 newp = (p - cStart)*8 + r; 8413 pi[newp] = p; 8414 } 8415 } 8416 break; 8417 case REFINER_HYBRID_HEX_3D: 8418 for (p = cStart; p < cMax; ++p) { 8419 for (r = 0; r < 8; ++r) { 8420 newp = (p - cStart)*8 + r; 8421 pi[newp] = p; 8422 } 8423 } 8424 for (p = cMax; p < cEnd; ++p) { 8425 for (r = 0; r < 4; ++r) { 8426 newp = (cMax - cStart)*8 + (p - cMax)*4 + r; 8427 pi[newp] = p; 8428 } 8429 } 8430 break; 8431 default: 8432 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8433 } 8434 parentId = pi; 8435 } else { 8436 /* The refiner needs midpoint vertices on hybrid edges and hybrid cells */ 8437 if (REFINER_HYBRID_SIMPLEX_TO_HEX_2D == refiner) { cMax = cEnd; eMax = eEnd; } 8438 ierr = PetscSectionSetChart(coordSectionNew, vStartNew, vStartNew+numVertices);CHKERRQ(ierr); 8439 } 8440 8441 /* All vertices have the spaceDim coordinates */ 8442 if (localize) { 8443 PetscInt c; 8444 8445 for (c = cStartNew; c < cEndNew; ++c) { 8446 PetscInt *cone = NULL; 8447 PetscInt closureSize, coneSize = 0, p, pdof; 8448 8449 ierr = PetscSectionGetDof(coordSection, parentId[c], &pdof); CHKERRQ(ierr); 8450 if (pdof) { /* localize on all cells that are refinement of a localized parent cell */ 8451 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8452 for (p = 0; p < closureSize*2; p += 2) { 8453 const PetscInt point = cone[p]; 8454 if ((point >= vStartNew) && (point < vEndNew)) coneSize++; 8455 } 8456 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8457 ierr = PetscSectionSetDof(coordSectionNew, c, coneSize*spaceDim);CHKERRQ(ierr); 8458 ierr = PetscSectionSetFieldDof(coordSectionNew, c, 0, coneSize*spaceDim);CHKERRQ(ierr); 8459 } 8460 } 8461 } 8462 for (v = vStartNew; v < vStartNew+numVertices; ++v) { 8463 ierr = PetscSectionSetDof(coordSectionNew, v, spaceDim);CHKERRQ(ierr); 8464 ierr = PetscSectionSetFieldDof(coordSectionNew, v, 0, spaceDim);CHKERRQ(ierr); 8465 } 8466 ierr = PetscSectionSetUp(coordSectionNew);CHKERRQ(ierr); 8467 ierr = DMSetCoordinateSection(rdm, PETSC_DETERMINE, coordSectionNew);CHKERRQ(ierr); 8468 ierr = DMGetCoordinatesLocal(dm, &coordinates);CHKERRQ(ierr); 8469 ierr = PetscSectionGetStorageSize(coordSectionNew, &coordSizeNew);CHKERRQ(ierr); 8470 ierr = VecCreate(PETSC_COMM_SELF, &coordinatesNew);CHKERRQ(ierr); 8471 ierr = PetscObjectSetName((PetscObject) coordinatesNew, "coordinates");CHKERRQ(ierr); 8472 ierr = VecSetSizes(coordinatesNew, coordSizeNew, PETSC_DETERMINE);CHKERRQ(ierr); 8473 ierr = VecGetBlockSize(coordinates, &bs);CHKERRQ(ierr); 8474 ierr = VecSetBlockSize(coordinatesNew, bs);CHKERRQ(ierr); 8475 ierr = VecGetType(coordinates, &vtype);CHKERRQ(ierr); 8476 ierr = VecSetType(coordinatesNew, vtype);CHKERRQ(ierr); 8477 ierr = VecGetArray(coordinates, &coords);CHKERRQ(ierr); 8478 ierr = VecGetArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8479 8480 switch (refiner) { 8481 case REFINER_NOOP: break; 8482 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 8483 case REFINER_SIMPLEX_TO_HEX_3D: 8484 case REFINER_HEX_3D: 8485 case REFINER_HYBRID_HEX_3D: 8486 /* Face vertices have the average of corner coordinates */ 8487 for (f = fStart; f < fMax; ++f) { 8488 const PetscInt newv = vStartNew + (vEnd - vStart) + (eMax - eStart) + (f - fStart); 8489 PetscInt *cone = NULL; 8490 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d; 8491 8492 ierr = DMPlexGetTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8493 for (p = 0; p < closureSize*2; p += 2) { 8494 const PetscInt point = cone[p]; 8495 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8496 } 8497 if (localize) { 8498 const PetscInt *support = NULL; 8499 PetscInt *rStar = NULL; 8500 PetscInt supportSize, rStarSize, coff, s, ccoff[8]; 8501 PetscBool cellfound = PETSC_FALSE; 8502 8503 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8504 ierr = DMPlexGetSupportSize(dm,f,&supportSize);CHKERRQ(ierr); 8505 ierr = DMPlexGetSupport(dm,f,&support);CHKERRQ(ierr); 8506 /* Compute average of coordinates for each cell sharing the face */ 8507 for (s = 0; s < supportSize; ++s) { 8508 PetscScalar coordsNewAux[3] = { 0.0, 0.0, 0.0 }; 8509 PetscInt *cellCone = NULL; 8510 PetscInt cellClosureSize, cellConeSize = 0, cdof; 8511 const PetscInt cell = support[s]; 8512 PetscBool copyoff = PETSC_FALSE; 8513 8514 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8515 for (p = 0; p < cellClosureSize*2; p += 2) { 8516 const PetscInt point = cellCone[p]; 8517 if ((point >= vStart) && (point < vEnd)) cellCone[cellConeSize++] = point; 8518 } 8519 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8520 if (!cdof) { /* the parent cell does not have localized coordinates */ 8521 cellfound = PETSC_TRUE; 8522 for (v = 0; v < coneSize; ++v) { 8523 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8524 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] += coords[off[v]+d]; 8525 } 8526 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8527 } else { 8528 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8529 for (p = 0; p < coneSize; ++p) { 8530 const PetscInt tv = cone[p]; 8531 PetscInt cv, voff; 8532 PetscBool locv = PETSC_TRUE; 8533 8534 for (cv = 0; cv < cellConeSize; ++cv) { 8535 if (cellCone[cv] == tv) { 8536 ccoff[p] = spaceDim*cv + coff; 8537 break; 8538 } 8539 } 8540 if (cv == cellConeSize) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map vertex %D",tv); 8541 8542 ierr = PetscSectionGetOffset(coordSection, cone[p], &voff);CHKERRQ(ierr); 8543 for (d = 0; d < spaceDim; ++d) { 8544 coordsNewAux[d] += coords[ccoff[p]+d]; 8545 if (!cellfound && coords[voff+d] != coords[ccoff[p]+d]) locv = PETSC_FALSE; 8546 } 8547 if (locv && !cellfound) { 8548 cellfound = PETSC_TRUE; 8549 copyoff = PETSC_TRUE; 8550 } 8551 } 8552 for (d = 0; d < spaceDim; ++d) coordsNewAux[d] /= coneSize; 8553 8554 /* Found a valid face for the "vertex" part of the Section (physical space) 8555 i.e., a face that has at least one corner in the physical space */ 8556 if (copyoff) for (p = 0; p < coneSize; ++p) off[p] = ccoff[p]; 8557 } 8558 8559 /* Localize new coordinates on each refined cell */ 8560 for (v = 0; v < rStarSize*2; v += 2) { 8561 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew) && parentId[rStar[v]-cStartNew] == cell) { 8562 PetscInt *rcone = NULL, rclosureSize, lid, rcdof, rcoff; 8563 const PetscInt rcell = rStar[v]; 8564 8565 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8566 if (!rcdof) continue; 8567 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &rcoff);CHKERRQ(ierr); 8568 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8569 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8570 if (rcone[p] == newv) { 8571 for (d = 0; d < spaceDim; d++) coordsNew[rcoff + lid*spaceDim + d] = coordsNewAux[d]; 8572 break; 8573 } 8574 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8575 } 8576 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8577 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8578 } 8579 } 8580 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8581 } 8582 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8583 if (!cellfound) { 8584 /* Could not find a valid face for the vertex part, we will get this vertex later (final reduction) */ 8585 needcoords = PETSC_TRUE; 8586 coneSize = 0; 8587 } 8588 } else { 8589 for (v = 0; v < coneSize; ++v) { 8590 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8591 } 8592 } 8593 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8594 if (coneSize) { 8595 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8596 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8597 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8598 } else { 8599 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8600 } 8601 ierr = DMPlexRestoreTransitiveClosure(dm, f, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8602 } 8603 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 8604 case REFINER_SIMPLEX_TO_HEX_2D: 8605 case REFINER_HEX_2D: 8606 case REFINER_HYBRID_HEX_2D: 8607 case REFINER_SIMPLEX_1D: 8608 /* Cell vertices have the average of corner coordinates */ 8609 for (c = cStart; c < cMax; ++c) { 8610 const PetscInt newv = vStartNew + (vEnd - vStart) + (dim > 1 ? (eMax - eStart) : 0) + (c - cStart) + (dim > 2 ? (fMax - fStart) : 0); 8611 PetscInt *cone = NULL; 8612 PetscInt closureSize, coneSize = 0, off[8], offnew, p, d, cdof = 0; 8613 8614 ierr = DMPlexGetTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8615 for (p = 0; p < closureSize*2; p += 2) { 8616 const PetscInt point = cone[p]; 8617 if ((point >= vStart) && (point < vEnd)) cone[coneSize++] = point; 8618 } 8619 if (localize) { 8620 ierr = PetscSectionGetDof(coordSection, c, &cdof);CHKERRQ(ierr); 8621 } 8622 if (cdof) { 8623 PetscInt coff; 8624 8625 ierr = PetscSectionGetOffset(coordSection, c, &coff);CHKERRQ(ierr); 8626 for (v = 0; v < coneSize; ++v) off[v] = spaceDim*v + coff; 8627 } else { 8628 for (v = 0; v < coneSize; ++v) { 8629 ierr = PetscSectionGetOffset(coordSection, cone[v], &off[v]);CHKERRQ(ierr); 8630 } 8631 } 8632 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8633 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = 0.0; 8634 for (v = 0; v < coneSize; ++v) {ierr = DMLocalizeAddCoordinate_Internal(dm, spaceDim, &coords[off[0]], &coords[off[v]], &coordsNew[offnew]);CHKERRQ(ierr);} 8635 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] /= coneSize; 8636 ierr = DMPlexRestoreTransitiveClosure(dm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8637 8638 /* Localize new coordinates on each refined cell */ 8639 if (cdof) { 8640 PetscInt *rStar = NULL, rStarSize; 8641 8642 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8643 for (v = 0; v < rStarSize*2; v += 2) { 8644 if ((rStar[v] >= cStartNew) && (rStar[v] < cEndNew)) { 8645 PetscInt *cone = NULL, closureSize, lid, coff, rc, rcdof; 8646 8647 rc = rStar[v]; 8648 ierr = PetscSectionGetDof(coordSectionNew, rc, &rcdof);CHKERRQ(ierr); 8649 if (!rcdof) continue; 8650 ierr = PetscSectionGetOffset(coordSectionNew, rc, &coff);CHKERRQ(ierr); 8651 ierr = DMPlexGetTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8652 for (p = 0, lid = 0; p < closureSize*2; p += 2) { 8653 if (cone[p] == newv) { 8654 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNew[offnew + d]; 8655 break; 8656 } 8657 if (cone[p] >= vStartNew && cone[p] < vEndNew) lid++; 8658 } 8659 if (p == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8660 ierr = DMPlexRestoreTransitiveClosure(rdm, rc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8661 } 8662 } 8663 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8664 } 8665 } 8666 case REFINER_SIMPLEX_2D: 8667 case REFINER_HYBRID_SIMPLEX_2D: 8668 case REFINER_SIMPLEX_3D: 8669 case REFINER_HYBRID_SIMPLEX_3D: 8670 /* Edge vertices have the average of endpoint coordinates */ 8671 for (e = eStart; e < eMax; ++e) { 8672 const PetscInt newv = vStartNew + (vEnd - vStart) + (e - eStart); 8673 const PetscInt *cone; 8674 PetscInt coneSize, offA, offB, offnew, d; 8675 8676 ierr = DMPlexGetConeSize(dm, e, &coneSize);CHKERRQ(ierr); 8677 if (coneSize != 2) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Edge %D cone should have two vertices, not %D", e, coneSize); 8678 ierr = DMPlexGetCone(dm, e, &cone);CHKERRQ(ierr); 8679 if (localize) { 8680 PetscInt coff, toffA = -1, toffB = -1, voffA, voffB; 8681 PetscInt *eStar = NULL, eStarSize; 8682 PetscInt *rStar = NULL, rStarSize; 8683 PetscBool cellfound = PETSC_FALSE; 8684 8685 offA = offB = -1; 8686 ierr = PetscSectionGetOffset(coordSection, cone[0], &voffA);CHKERRQ(ierr); 8687 ierr = PetscSectionGetOffset(coordSection, cone[1], &voffB);CHKERRQ(ierr); 8688 ierr = DMPlexGetTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8689 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8690 for (v = 0; v < eStarSize*2; v += 2) { 8691 if ((eStar[v] >= cStart) && (eStar[v] < cEnd)) { 8692 PetscScalar coordsNewAux[3] = {0., 0., 0.}; 8693 PetscInt *cellCone = NULL; 8694 PetscInt cellClosureSize, s, cv, cdof; 8695 PetscBool locvA = PETSC_TRUE, locvB = PETSC_TRUE; 8696 const PetscInt cell = eStar[v]; 8697 8698 ierr = PetscSectionGetDof(coordSection, cell, &cdof);CHKERRQ(ierr); 8699 if (!cdof) { 8700 /* Found a valid edge for the "vertex" part of the Section */ 8701 offA = voffA; 8702 offB = voffB; 8703 cellfound = PETSC_TRUE; 8704 } else { 8705 ierr = PetscSectionGetOffset(coordSection, cell, &coff);CHKERRQ(ierr); 8706 ierr = DMPlexGetTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8707 for (s = 0, cv = 0; s < cellClosureSize*2; s += 2) { 8708 const PetscInt point = cellCone[s]; 8709 if ((point >= vStart) && (point < vEnd)) { 8710 if (point == cone[0]) toffA = spaceDim*cv + coff; 8711 else if (point == cone[1]) toffB = spaceDim*cv + coff; 8712 cv++; 8713 } 8714 } 8715 ierr = DMPlexRestoreTransitiveClosure(dm, cell, PETSC_TRUE, &cellClosureSize, &cellCone);CHKERRQ(ierr); 8716 for (d = 0; d < spaceDim; ++d) { 8717 coordsNewAux[d] = 0.5*(coords[toffA+d] + coords[toffB+d]); 8718 if (coords[toffA+d] != coords[voffA+d]) locvA = PETSC_FALSE; 8719 if (coords[toffB+d] != coords[voffB+d]) locvB = PETSC_FALSE; 8720 } 8721 /* Found a valid edge for the "vertex" part of the Section */ 8722 if (!cellfound && (locvA || locvB)) { 8723 cellfound = PETSC_TRUE; 8724 offA = toffA; 8725 offB = toffB; 8726 } 8727 } 8728 8729 /* Localize new coordinates on each refined cell */ 8730 for (s = 0; s < rStarSize*2; s += 2) { 8731 if ((rStar[s] >= cStartNew) && (rStar[s] < cEndNew) && parentId[rStar[s]-cStartNew] == cell) { 8732 PetscInt *rcone = NULL, rclosureSize, lid, p, rcdof; 8733 const PetscInt rcell = rStar[s]; 8734 8735 ierr = PetscSectionGetDof(coordSectionNew, rcell, &rcdof);CHKERRQ(ierr); 8736 if (!rcdof) continue; 8737 ierr = PetscSectionGetOffset(coordSectionNew, rcell, &coff);CHKERRQ(ierr); 8738 ierr = DMPlexGetTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8739 for (p = 0, lid = 0; p < rclosureSize*2; p += 2) { 8740 if (rcone[p] == newv) { 8741 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = coordsNewAux[d]; 8742 break; 8743 } 8744 if (rcone[p] >= vStartNew && rcone[p] < vEndNew) lid++; 8745 } 8746 ierr = DMPlexRestoreTransitiveClosure(rdm, rcell, PETSC_TRUE, &rclosureSize, &rcone);CHKERRQ(ierr); 8747 if (p == rclosureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8748 } 8749 } 8750 } 8751 } 8752 ierr = DMPlexRestoreTransitiveClosure(dm, e, PETSC_FALSE, &eStarSize, &eStar);CHKERRQ(ierr); 8753 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8754 if (!cellfound) { 8755 /* Could not find a valid edge for the vertex part, we will get this vertex later (final reduction) */ 8756 needcoords = PETSC_TRUE; 8757 } 8758 } else { 8759 ierr = PetscSectionGetOffset(coordSection, cone[0], &offA);CHKERRQ(ierr); 8760 ierr = PetscSectionGetOffset(coordSection, cone[1], &offB);CHKERRQ(ierr); 8761 } 8762 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8763 if (offA != -1 && offB != -1) { 8764 ierr = DMLocalizeCoordinate_Internal(dm, spaceDim, &coords[offA], &coords[offB], &coordsNew[offnew]);CHKERRQ(ierr); 8765 for (d = 0; d < spaceDim; ++d) { 8766 coordsNew[offnew+d] = 0.5*(coords[offA+d] + coordsNew[offnew+d]); 8767 ierr = DMPlexSnapToGeomModel(dm, e, &coordsNew[offnew], &coordsNew[offnew]);CHKERRQ(ierr); 8768 } 8769 } else { 8770 for (d = 0; d < spaceDim; ++d) coordsNew[offnew+d] = PETSC_MIN_REAL; 8771 } 8772 } 8773 /* Old vertices have the same coordinates */ 8774 for (v = vStart; v < vEnd; ++v) { 8775 const PetscInt newv = vStartNew + (v - vStart); 8776 PetscInt off, offnew, d; 8777 8778 ierr = PetscSectionGetOffset(coordSection, v, &off);CHKERRQ(ierr); 8779 ierr = PetscSectionGetOffset(coordSectionNew, newv, &offnew);CHKERRQ(ierr); 8780 for (d = 0; d < spaceDim; ++d) { 8781 coordsNew[offnew+d] = coords[off+d]; 8782 } 8783 8784 /* Localize new coordinates on each refined cell */ 8785 if (localize) { 8786 PetscInt p; 8787 PetscInt *rStar = NULL, rStarSize; 8788 8789 ierr = DMPlexGetTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8790 for (p = 0; p < rStarSize*2; p += 2) { 8791 if ((rStar[p] >= cStartNew) && (rStar[p] < cEndNew)) { 8792 PetscScalar ocoords[3] = {0,0,0}; /* dummy values for compiler warnings about uninitialized values */ 8793 PetscInt *cone = NULL, closureSize, lid, coff, s, oc, cdof; 8794 8795 c = rStar[p]; 8796 oc = parentId[c-cStartNew]; 8797 ierr = PetscSectionGetDof(coordSectionNew, c, &cdof);CHKERRQ(ierr); 8798 if (!cdof) continue; 8799 ierr = PetscSectionGetDof(coordSection, oc, &cdof);CHKERRQ(ierr); 8800 if (!cdof) continue; 8801 ierr = PetscSectionGetOffset(coordSection, oc, &coff);CHKERRQ(ierr); 8802 ierr = DMPlexGetTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8803 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8804 if (cone[s] == v) { 8805 for (d = 0; d < spaceDim; d++) ocoords[d] = coords[coff + lid*spaceDim + d]; 8806 break; 8807 } 8808 if (cone[s] >= vStart && cone[s] < vEnd) lid++; 8809 } 8810 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map old vertex %D",v); 8811 ierr = DMPlexRestoreTransitiveClosure(dm, oc, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8812 8813 ierr = PetscSectionGetOffset(coordSectionNew, c, &coff);CHKERRQ(ierr); 8814 ierr = DMPlexGetTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8815 for (s = 0, lid = 0; s < closureSize*2; s += 2) { 8816 if (cone[s] == newv) { 8817 for (d = 0; d < spaceDim; d++) coordsNew[coff + lid*spaceDim + d] = ocoords[d]; 8818 break; 8819 } 8820 if (cone[s] >= vStartNew && cone[s] < vEndNew) lid++; 8821 } 8822 if (s == closureSize*2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unable to map new vertex %D",newv); 8823 ierr = DMPlexRestoreTransitiveClosure(rdm, c, PETSC_TRUE, &closureSize, &cone);CHKERRQ(ierr); 8824 } 8825 } 8826 ierr = DMPlexRestoreTransitiveClosure(rdm, newv, PETSC_FALSE, &rStarSize, &rStar);CHKERRQ(ierr); 8827 } 8828 } 8829 break; 8830 default: 8831 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 8832 } 8833 ierr = VecRestoreArray(coordinates, &coords);CHKERRQ(ierr); 8834 ierr = VecRestoreArray(coordinatesNew, &coordsNew);CHKERRQ(ierr); 8835 ierr = DMSetCoordinatesLocal(rdm, coordinatesNew);CHKERRQ(ierr); 8836 8837 /* Final reduction (if needed) if we are localizing */ 8838 if (localize) { 8839 PetscBool gred; 8840 8841 ierr = MPIU_Allreduce(&needcoords, &gred, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)rdm));CHKERRQ(ierr); 8842 if (gred) { 8843 DM cdm; 8844 Vec aux; 8845 PetscSF sf; 8846 const PetscScalar *lArray; 8847 PetscScalar *gArray; 8848 #if defined(PETSC_USE_COMPLEX) 8849 PetscInt i, ln, gn; 8850 PetscReal *lrArray; 8851 PetscReal *grArray; 8852 #endif 8853 8854 ierr = DMGetCoordinateDM(rdm, &cdm);CHKERRQ(ierr); 8855 ierr = DMCreateGlobalVector(cdm, &aux);CHKERRQ(ierr); 8856 ierr = DMGetSectionSF(cdm, &sf);CHKERRQ(ierr); 8857 ierr = VecGetArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8858 ierr = VecSet(aux, PETSC_MIN_REAL);CHKERRQ(ierr); 8859 ierr = VecGetArray(aux, &gArray);CHKERRQ(ierr); 8860 #if defined(PETSC_USE_COMPLEX) 8861 ierr = VecGetLocalSize(aux, &gn);CHKERRQ(ierr); 8862 ierr = VecGetLocalSize(coordinatesNew, &ln);CHKERRQ(ierr); 8863 ierr = PetscMalloc2(ln,&lrArray,gn,&grArray);CHKERRQ(ierr); 8864 for (i=0;i<ln;i++) lrArray[i] = PetscRealPart(lArray[i]); 8865 for (i=0;i<gn;i++) grArray[i] = PetscRealPart(gArray[i]); 8866 ierr = PetscSFReduceBegin(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8867 ierr = PetscSFReduceEnd(sf, MPIU_REAL, lrArray, grArray, MPIU_MAX);CHKERRQ(ierr); 8868 for (i=0;i<gn;i++) gArray[i] = grArray[i]; 8869 ierr = PetscFree2(lrArray,grArray);CHKERRQ(ierr); 8870 #else 8871 ierr = PetscSFReduceBegin(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8872 ierr = PetscSFReduceEnd(sf, MPIU_SCALAR, lArray, gArray, MPIU_MAX);CHKERRQ(ierr); 8873 #endif 8874 ierr = VecRestoreArrayRead(coordinatesNew, &lArray);CHKERRQ(ierr); 8875 ierr = VecRestoreArray(aux, &gArray);CHKERRQ(ierr); 8876 ierr = DMGlobalToLocalBegin(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8877 ierr = DMGlobalToLocalEnd(cdm, aux, INSERT_VALUES, coordinatesNew);CHKERRQ(ierr); 8878 ierr = VecDestroy(&aux);CHKERRQ(ierr); 8879 } 8880 } 8881 ierr = VecDestroy(&coordinatesNew);CHKERRQ(ierr); 8882 ierr = PetscSectionDestroy(&coordSectionNew);CHKERRQ(ierr); 8883 ierr = PetscFree(parentId);CHKERRQ(ierr); 8884 PetscFunctionReturn(0); 8885 } 8886 8887 /*@ 8888 DMPlexCreateProcessSF - Create an SF which just has process connectivity 8889 8890 Collective on dm 8891 8892 Input Parameters: 8893 + dm - The DM 8894 - sfPoint - The PetscSF which encodes point connectivity 8895 8896 Output Parameters: 8897 + processRanks - A list of process neighbors, or NULL 8898 - sfProcess - An SF encoding the process connectivity, or NULL 8899 8900 Level: developer 8901 8902 .seealso: PetscSFCreate(), DMPlexCreateTwoSidedProcessSF() 8903 @*/ 8904 PetscErrorCode DMPlexCreateProcessSF(DM dm, PetscSF sfPoint, IS *processRanks, PetscSF *sfProcess) 8905 { 8906 PetscInt numRoots, numLeaves, l; 8907 const PetscInt *localPoints; 8908 const PetscSFNode *remotePoints; 8909 PetscInt *localPointsNew; 8910 PetscSFNode *remotePointsNew; 8911 PetscInt *ranks, *ranksNew; 8912 PetscMPIInt size; 8913 PetscErrorCode ierr; 8914 8915 PetscFunctionBegin; 8916 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 8917 PetscValidHeaderSpecific(sfPoint, PETSCSF_CLASSID, 2); 8918 if (processRanks) {PetscValidPointer(processRanks, 3);} 8919 if (sfProcess) {PetscValidPointer(sfProcess, 4);} 8920 ierr = MPI_Comm_size(PetscObjectComm((PetscObject) dm), &size);CHKERRQ(ierr); 8921 ierr = PetscSFGetGraph(sfPoint, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8922 ierr = PetscMalloc1(numLeaves, &ranks);CHKERRQ(ierr); 8923 for (l = 0; l < numLeaves; ++l) { 8924 ranks[l] = remotePoints[l].rank; 8925 } 8926 ierr = PetscSortRemoveDupsInt(&numLeaves, ranks);CHKERRQ(ierr); 8927 ierr = PetscMalloc1(numLeaves, &ranksNew);CHKERRQ(ierr); 8928 ierr = PetscMalloc1(numLeaves, &localPointsNew);CHKERRQ(ierr); 8929 ierr = PetscMalloc1(numLeaves, &remotePointsNew);CHKERRQ(ierr); 8930 for (l = 0; l < numLeaves; ++l) { 8931 ranksNew[l] = ranks[l]; 8932 localPointsNew[l] = l; 8933 remotePointsNew[l].index = 0; 8934 remotePointsNew[l].rank = ranksNew[l]; 8935 } 8936 ierr = PetscFree(ranks);CHKERRQ(ierr); 8937 if (processRanks) {ierr = ISCreateGeneral(PetscObjectComm((PetscObject)dm), numLeaves, ranksNew, PETSC_OWN_POINTER, processRanks);CHKERRQ(ierr);} 8938 else {ierr = PetscFree(ranksNew);CHKERRQ(ierr);} 8939 if (sfProcess) { 8940 ierr = PetscSFCreate(PetscObjectComm((PetscObject)dm), sfProcess);CHKERRQ(ierr); 8941 ierr = PetscObjectSetName((PetscObject) *sfProcess, "Process SF");CHKERRQ(ierr); 8942 ierr = PetscSFSetFromOptions(*sfProcess);CHKERRQ(ierr); 8943 ierr = PetscSFSetGraph(*sfProcess, size, numLeaves, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 8944 } 8945 PetscFunctionReturn(0); 8946 } 8947 8948 static PetscErrorCode CellRefinerCreateSF(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 8949 { 8950 PetscSF sf, sfNew, sfProcess; 8951 IS processRanks; 8952 MPI_Datatype depthType; 8953 PetscInt numRoots, numLeaves, numLeavesNew = 0, l, m; 8954 const PetscInt *localPoints, *neighbors; 8955 const PetscSFNode *remotePoints; 8956 PetscInt *localPointsNew; 8957 PetscSFNode *remotePointsNew; 8958 PetscInt *depthSizeOld, *rdepthSize, *rdepthSizeOld, *rdepthMaxOld, *rvStart, *rvStartNew, *reStart, *reStartNew, *rfStart, *rfStartNew, *rcStart, *rcStartNew; 8959 PetscInt ldepth, depth, numNeighbors, pStartNew, pEndNew, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r, n; 8960 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 8961 PetscErrorCode ierr; 8962 8963 PetscFunctionBegin; 8964 ierr = DMPlexGetChart(rdm, &pStartNew, &pEndNew);CHKERRQ(ierr); 8965 ierr = DMPlexGetDepth(dm, &ldepth);CHKERRQ(ierr); 8966 ierr = MPIU_Allreduce(&ldepth, &depth, 1, MPIU_INT, MPI_MAX, PetscObjectComm((PetscObject) dm));CHKERRQ(ierr); 8967 if ((ldepth >= 0) && (depth != ldepth)) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Inconsistent Plex depth %D != %D", ldepth, depth); 8968 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 8969 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 8970 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 8971 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 8972 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 8973 cMax = cMax < 0 ? cEnd : cMax; 8974 fMax = fMax < 0 ? fEnd : fMax; 8975 eMax = eMax < 0 ? eEnd : eMax; 8976 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 8977 ierr = DMGetPointSF(dm, &sf);CHKERRQ(ierr); 8978 ierr = DMGetPointSF(rdm, &sfNew);CHKERRQ(ierr); 8979 /* Calculate size of new SF */ 8980 ierr = PetscSFGetGraph(sf, &numRoots, &numLeaves, &localPoints, &remotePoints);CHKERRQ(ierr); 8981 if (numRoots < 0) PetscFunctionReturn(0); 8982 for (l = 0; l < numLeaves; ++l) { 8983 const PetscInt p = localPoints[l]; 8984 8985 switch (refiner) { 8986 case REFINER_SIMPLEX_1D: 8987 if ((p >= vStart) && (p < vEnd)) { 8988 /* Interior vertices stay the same */ 8989 ++numLeavesNew; 8990 } else if ((p >= cStart && p < cMax)) { 8991 /* Interior cells add new cells and interior vertices */ 8992 numLeavesNew += 2 + 1; 8993 } 8994 break; 8995 case REFINER_SIMPLEX_2D: 8996 case REFINER_HYBRID_SIMPLEX_2D: 8997 if ((p >= vStart) && (p < vEnd)) { 8998 /* Interior vertices stay the same */ 8999 ++numLeavesNew; 9000 } else if ((p >= fStart) && (p < fMax)) { 9001 /* Interior faces add new faces and vertex */ 9002 numLeavesNew += 2 + 1; 9003 } else if ((p >= fMax) && (p < fEnd)) { 9004 /* Hybrid faces stay the same */ 9005 ++numLeavesNew; 9006 } else if ((p >= cStart) && (p < cMax)) { 9007 /* Interior cells add new cells and interior faces */ 9008 numLeavesNew += 4 + 3; 9009 } else if ((p >= cMax) && (p < cEnd)) { 9010 /* Hybrid cells add new cells and hybrid face */ 9011 numLeavesNew += 2 + 1; 9012 } 9013 break; 9014 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9015 case REFINER_SIMPLEX_TO_HEX_2D: 9016 if ((p >= vStart) && (p < vEnd)) { 9017 /* Interior vertices stay the same */ 9018 ++numLeavesNew; 9019 } else if ((p >= fStart) && (p < fEnd)) { 9020 /* Interior faces add new faces and vertex */ 9021 numLeavesNew += 2 + 1; 9022 } else if ((p >= cStart) && (p < cMax)) { 9023 /* Interior cells add new cells, interior faces, and vertex */ 9024 numLeavesNew += 3 + 3 + 1; 9025 } else if ((p >= cMax) && (p < cEnd)) { 9026 /* Hybrid cells add new cells, interior faces, and vertex */ 9027 numLeavesNew += 4 + 4 + 1; 9028 } 9029 break; 9030 case REFINER_HEX_2D: 9031 case REFINER_HYBRID_HEX_2D: 9032 if ((p >= vStart) && (p < vEnd)) { 9033 /* Interior vertices stay the same */ 9034 ++numLeavesNew; 9035 } else if ((p >= fStart) && (p < fMax)) { 9036 /* Interior faces add new faces and vertex */ 9037 numLeavesNew += 2 + 1; 9038 } else if ((p >= fMax) && (p < fEnd)) { 9039 /* Hybrid faces stay the same */ 9040 ++numLeavesNew; 9041 } else if ((p >= cStart) && (p < cMax)) { 9042 /* Interior cells add new cells, interior faces, and vertex */ 9043 numLeavesNew += 4 + 4 + 1; 9044 } else if ((p >= cMax) && (p < cEnd)) { 9045 /* Hybrid cells add new cells and hybrid face */ 9046 numLeavesNew += 2 + 1; 9047 } 9048 break; 9049 case REFINER_SIMPLEX_3D: 9050 case REFINER_HYBRID_SIMPLEX_3D: 9051 if ((p >= vStart) && (p < vEnd)) { 9052 /* Interior vertices stay the same */ 9053 ++numLeavesNew; 9054 } else if ((p >= eStart) && (p < eMax)) { 9055 /* Interior edges add new edges and vertex */ 9056 numLeavesNew += 2 + 1; 9057 } else if ((p >= eMax) && (p < eEnd)) { 9058 /* Hybrid edges stay the same */ 9059 ++numLeavesNew; 9060 } else if ((p >= fStart) && (p < fMax)) { 9061 /* Interior faces add new faces and edges */ 9062 numLeavesNew += 4 + 3; 9063 } else if ((p >= fMax) && (p < fEnd)) { 9064 /* Hybrid faces add new faces and edges */ 9065 numLeavesNew += 2 + 1; 9066 } else if ((p >= cStart) && (p < cMax)) { 9067 /* Interior cells add new cells, faces, and edges */ 9068 numLeavesNew += 8 + 8 + 1; 9069 } else if ((p >= cMax) && (p < cEnd)) { 9070 /* Hybrid cells add new cells and faces */ 9071 numLeavesNew += 4 + 3; 9072 } 9073 break; 9074 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9075 case REFINER_SIMPLEX_TO_HEX_3D: 9076 if ((p >= vStart) && (p < vEnd)) { 9077 /* Interior vertices stay the same */ 9078 ++numLeavesNew; 9079 } else if ((p >= eStart) && (p < eMax)) { 9080 /* Interior edges add new edges and vertex */ 9081 numLeavesNew += 2 + 1; 9082 } else if ((p >= eMax) && (p < eEnd)) { 9083 /* Hybrid edges stay the same */ 9084 ++numLeavesNew; 9085 } else if ((p >= fStart) && (p < fMax)) { 9086 /* Interior faces add new faces, edges and a vertex */ 9087 numLeavesNew += 3 + 3 + 1; 9088 } else if ((p >= fMax) && (p < fEnd)) { 9089 /* Hybrid faces add new faces and an edge */ 9090 numLeavesNew += 2 + 1; 9091 } else if ((p >= cStart) && (p < cMax)) { 9092 /* Interior cells add new cells, faces, edges and a vertex */ 9093 numLeavesNew += 4 + 6 + 4 + 1; 9094 } else if ((p >= cMax) && (p < cEnd)) { 9095 /* Hybrid cells add new cells, faces and an edge */ 9096 numLeavesNew += 3 + 3 + 1; 9097 } 9098 break; 9099 case REFINER_HEX_3D: 9100 case REFINER_HYBRID_HEX_3D: 9101 if ((p >= vStart) && (p < vEnd)) { 9102 /* Old vertices stay the same */ 9103 ++numLeavesNew; 9104 } else if ((p >= eStart) && (p < eMax)) { 9105 /* Interior edges add new edges, and vertex */ 9106 numLeavesNew += 2 + 1; 9107 } else if ((p >= eMax) && (p < eEnd)) { 9108 /* Hybrid edges stay the same */ 9109 ++numLeavesNew; 9110 } else if ((p >= fStart) && (p < fMax)) { 9111 /* Interior faces add new faces, edges, and vertex */ 9112 numLeavesNew += 4 + 4 + 1; 9113 } else if ((p >= fMax) && (p < fEnd)) { 9114 /* Hybrid faces add new faces and edges */ 9115 numLeavesNew += 2 + 1; 9116 } else if ((p >= cStart) && (p < cMax)) { 9117 /* Interior cells add new cells, faces, edges, and vertex */ 9118 numLeavesNew += 8 + 12 + 6 + 1; 9119 } else if ((p >= cStart) && (p < cEnd)) { 9120 /* Hybrid cells add new cells, faces, and edges */ 9121 numLeavesNew += 4 + 4 + 1; 9122 } 9123 break; 9124 default: 9125 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9126 } 9127 } 9128 /* Communicate depthSizes for each remote rank */ 9129 ierr = DMPlexCreateProcessSF(dm, sf, &processRanks, &sfProcess);CHKERRQ(ierr); 9130 ierr = ISGetLocalSize(processRanks, &numNeighbors);CHKERRQ(ierr); 9131 ierr = PetscMalloc5((depth+1)*numNeighbors,&rdepthSize,numNeighbors,&rvStartNew,numNeighbors,&reStartNew,numNeighbors,&rfStartNew,numNeighbors,&rcStartNew);CHKERRQ(ierr); 9132 ierr = PetscMalloc7(depth+1,&depthSizeOld,(depth+1)*numNeighbors,&rdepthSizeOld,(depth+1)*numNeighbors,&rdepthMaxOld,numNeighbors,&rvStart,numNeighbors,&reStart,numNeighbors,&rfStart,numNeighbors,&rcStart);CHKERRQ(ierr); 9133 ierr = MPI_Type_contiguous(depth+1, MPIU_INT, &depthType);CHKERRQ(ierr); 9134 ierr = MPI_Type_commit(&depthType);CHKERRQ(ierr); 9135 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9136 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSize, rdepthSize);CHKERRQ(ierr); 9137 for (n = 0; n < numNeighbors; ++n) { 9138 ierr = GetDepthStart_Private(depth, &rdepthSize[n*(depth+1)], &rcStartNew[n], &rfStartNew[n], &reStartNew[n], &rvStartNew[n]);CHKERRQ(ierr); 9139 } 9140 depthSizeOld[depth] = cMax; 9141 depthSizeOld[0] = vMax; 9142 depthSizeOld[depth-1] = fMax; 9143 depthSizeOld[1] = eMax; 9144 9145 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9146 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthMaxOld);CHKERRQ(ierr); 9147 9148 depthSizeOld[depth] = cEnd - cStart; 9149 depthSizeOld[0] = vEnd - vStart; 9150 depthSizeOld[depth-1] = fEnd - fStart; 9151 depthSizeOld[1] = eEnd - eStart; 9152 9153 ierr = PetscSFBcastBegin(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9154 ierr = PetscSFBcastEnd(sfProcess, depthType, depthSizeOld, rdepthSizeOld);CHKERRQ(ierr); 9155 for (n = 0; n < numNeighbors; ++n) { 9156 ierr = GetDepthStart_Private(depth, &rdepthSizeOld[n*(depth+1)], &rcStart[n], &rfStart[n], &reStart[n], &rvStart[n]);CHKERRQ(ierr); 9157 rdepthMaxOld[n*(depth+1)+depth] = rdepthMaxOld[n*(depth+1)+depth] < 0 ? rdepthSizeOld[n*(depth+1)+depth] +rcStart[n]: rdepthMaxOld[n*(depth+1)+depth]; 9158 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]; 9159 rdepthMaxOld[n*(depth+1)+1] = rdepthMaxOld[n*(depth+1)+1] < 0 ? rdepthSizeOld[n*(depth+1)+1] +reStart[n]: rdepthMaxOld[n*(depth+1)+1]; 9160 } 9161 ierr = MPI_Type_free(&depthType);CHKERRQ(ierr); 9162 ierr = PetscSFDestroy(&sfProcess);CHKERRQ(ierr); 9163 /* Calculate new point SF */ 9164 ierr = PetscMalloc1(numLeavesNew, &localPointsNew);CHKERRQ(ierr); 9165 ierr = PetscMalloc1(numLeavesNew, &remotePointsNew);CHKERRQ(ierr); 9166 ierr = ISGetIndices(processRanks, &neighbors);CHKERRQ(ierr); 9167 for (l = 0, m = 0; l < numLeaves; ++l) { 9168 PetscInt p = localPoints[l]; 9169 PetscInt rp = remotePoints[l].index, n; 9170 PetscMPIInt rrank = remotePoints[l].rank; 9171 9172 ierr = PetscFindInt(rrank, numNeighbors, neighbors, &n);CHKERRQ(ierr); 9173 if (n < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Could not locate remote rank %D", rrank); 9174 switch (refiner) { 9175 case REFINER_SIMPLEX_1D: 9176 if ((p >= vStart) && (p < vEnd)) { 9177 /* Old vertices stay the same */ 9178 localPointsNew[m] = vStartNew + (p - vStart); 9179 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9180 remotePointsNew[m].rank = rrank; 9181 ++m; 9182 } else if ((p >= cStart) && (p < cMax)) { 9183 /* Old interior cells add new cells and vertex */ 9184 for (r = 0; r < 2; ++r, ++m) { 9185 localPointsNew[m] = cStartNew + (p - cStart)*2 + r; 9186 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*2 + r; 9187 remotePointsNew[m].rank = rrank; 9188 } 9189 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - cStart); 9190 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rcStart[n]); 9191 remotePointsNew[m].rank = rrank; 9192 ++m; 9193 } 9194 break; 9195 case REFINER_SIMPLEX_2D: 9196 case REFINER_HYBRID_SIMPLEX_2D: 9197 if ((p >= vStart) && (p < vEnd)) { 9198 /* Old vertices stay the same */ 9199 localPointsNew[m] = vStartNew + (p - vStart); 9200 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9201 remotePointsNew[m].rank = rrank; 9202 ++m; 9203 } else if ((p >= fStart) && (p < fMax)) { 9204 /* Old interior faces add new faces and vertex */ 9205 for (r = 0; r < 2; ++r, ++m) { 9206 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9207 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9208 remotePointsNew[m].rank = rrank; 9209 } 9210 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9211 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9212 remotePointsNew[m].rank = rrank; 9213 ++m; 9214 } else if ((p >= fMax) && (p < fEnd)) { 9215 /* Old hybrid faces stay the same */ 9216 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9217 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9218 remotePointsNew[m].rank = rrank; 9219 ++m; 9220 } else if ((p >= cStart) && (p < cMax)) { 9221 /* Old interior cells add new cells and interior faces */ 9222 for (r = 0; r < 4; ++r, ++m) { 9223 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9224 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9225 remotePointsNew[m].rank = rrank; 9226 } 9227 for (r = 0; r < 3; ++r, ++m) { 9228 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*3 + r; 9229 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*3 + r; 9230 remotePointsNew[m].rank = rrank; 9231 } 9232 } else if ((p >= cMax) && (p < cEnd)) { 9233 /* Old hybrid cells add new cells and hybrid face */ 9234 for (r = 0; r < 2; ++r, ++m) { 9235 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9236 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9237 remotePointsNew[m].rank = rrank; 9238 } 9239 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9240 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]); 9241 remotePointsNew[m].rank = rrank; 9242 ++m; 9243 } 9244 break; 9245 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9246 case REFINER_SIMPLEX_TO_HEX_2D: 9247 if ((p >= vStart) && (p < vEnd)) { 9248 /* Old vertices stay the same */ 9249 localPointsNew[m] = vStartNew + (p - vStart); 9250 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9251 remotePointsNew[m].rank = rrank; 9252 ++m; 9253 } else if ((p >= fStart) && (p < fEnd)) { 9254 /* Old interior faces add new faces and vertex */ 9255 for (r = 0; r < 2; ++r, ++m) { 9256 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9257 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9258 remotePointsNew[m].rank = rrank; 9259 } 9260 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9261 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9262 remotePointsNew[m].rank = rrank; 9263 ++m; 9264 } else if ((p >= cStart) && (p < cMax)) { 9265 /* Old interior cells add new cells, interior faces, and a vertex */ 9266 for (r = 0; r < 3; ++r, ++m) { 9267 localPointsNew[m] = cStartNew + (p - cStart)*3 + r; 9268 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*3 + r; 9269 remotePointsNew[m].rank = rrank; 9270 } 9271 for (r = 0; r < 3; ++r, ++m) { 9272 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9273 remotePointsNew[m].index = rfStartNew[n] + rdepthSizeOld[n*(depth+1)+depth-1]*2 + (rp - rcStart[n])*3 + r; 9274 remotePointsNew[m].rank = rrank; 9275 } 9276 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9277 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9278 remotePointsNew[m].rank = rrank; 9279 ++m; 9280 } else if ((p >= cMax) && (p < cEnd)) { 9281 /* Old interior hybrid cells add new cells, interior faces, and a vertex */ 9282 for (r = 0; r < 4; ++r, ++m) { 9283 localPointsNew[m] = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9284 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*3 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9285 remotePointsNew[m].rank = rrank; 9286 } 9287 for (r = 0; r < 4; ++r, ++m) { 9288 localPointsNew[m] = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9289 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; 9290 remotePointsNew[m].rank = rrank; 9291 } 9292 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9293 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + rdepthSizeOld[n*(depth+1)+depth-1] + (rp - rcStart[n]); 9294 remotePointsNew[m].rank = rrank; 9295 ++m; 9296 } 9297 break; 9298 case REFINER_HEX_2D: 9299 case REFINER_HYBRID_HEX_2D: 9300 if ((p >= vStart) && (p < vEnd)) { 9301 /* Old vertices stay the same */ 9302 localPointsNew[m] = vStartNew + (p - vStart); 9303 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9304 remotePointsNew[m].rank = rrank; 9305 ++m; 9306 } else if ((p >= fStart) && (p < fMax)) { 9307 /* Old interior faces add new faces and vertex */ 9308 for (r = 0; r < 2; ++r, ++m) { 9309 localPointsNew[m] = fStartNew + (p - fStart)*2 + r; 9310 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*2 + r; 9311 remotePointsNew[m].rank = rrank; 9312 } 9313 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - fStart); 9314 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - rfStart[n]); 9315 remotePointsNew[m].rank = rrank; 9316 ++m; 9317 } else if ((p >= fMax) && (p < fEnd)) { 9318 /* Old hybrid faces stay the same */ 9319 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - fMax); 9320 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rdepthMaxOld[n*(depth+1)+depth-1]); 9321 remotePointsNew[m].rank = rrank; 9322 ++m; 9323 } else if ((p >= cStart) && (p < cMax)) { 9324 /* Old interior cells add new cells, interior faces, and vertex */ 9325 for (r = 0; r < 4; ++r, ++m) { 9326 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9327 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9328 remotePointsNew[m].rank = rrank; 9329 } 9330 for (r = 0; r < 4; ++r, ++m) { 9331 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (p - cStart)*4 + r; 9332 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*2 + (rp - rcStart[n])*4 + r; 9333 remotePointsNew[m].rank = rrank; 9334 } 9335 localPointsNew[m] = vStartNew + (vEnd - vStart) + (fMax - fStart) + (p - cStart); 9336 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]); 9337 remotePointsNew[m].rank = rrank; 9338 ++m; 9339 } else if ((p >= cStart) && (p < cMax)) { 9340 /* Old hybrid cells add new cells and hybrid face */ 9341 for (r = 0; r < 2; ++r, ++m) { 9342 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; /* TODO: is this a bug? */ 9343 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; /* TODO: is this a bug? */ 9344 remotePointsNew[m].rank = rrank; 9345 } 9346 localPointsNew[m] = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9347 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]); 9348 remotePointsNew[m].rank = rrank; 9349 ++m; 9350 } 9351 break; 9352 case REFINER_SIMPLEX_3D: 9353 case REFINER_HYBRID_SIMPLEX_3D: 9354 if ((p >= vStart) && (p < vEnd)) { 9355 /* Interior vertices stay the same */ 9356 localPointsNew[m] = vStartNew + (p - vStart); 9357 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9358 remotePointsNew[m].rank = rrank; 9359 ++m; 9360 } else if ((p >= eStart) && (p < eMax)) { 9361 /* Interior edges add new edges and vertex */ 9362 for (r = 0; r < 2; ++r, ++m) { 9363 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9364 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9365 remotePointsNew[m].rank = rrank; 9366 } 9367 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9368 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9369 remotePointsNew[m].rank = rrank; 9370 ++m; 9371 } else if ((p >= eMax) && (p < eEnd)) { 9372 /* Hybrid edges stay the same */ 9373 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 9374 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]); 9375 remotePointsNew[m].rank = rrank; 9376 ++m; 9377 } else if ((p >= fStart) && (p < fMax)) { 9378 /* Interior faces add new faces and edges */ 9379 for (r = 0; r < 4; ++r, ++m) { 9380 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9381 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9382 remotePointsNew[m].rank = rrank; 9383 } 9384 for (r = 0; r < 3; ++r, ++m) { 9385 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9386 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9387 remotePointsNew[m].rank = rrank; 9388 } 9389 } else if ((p >= fMax) && (p < fEnd)) { 9390 /* Hybrid faces add new faces and edges */ 9391 for (r = 0; r < 2; ++r, ++m) { 9392 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 9393 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; 9394 remotePointsNew[m].rank = rrank; 9395 } 9396 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (eEnd - eMax) + (p - fMax); 9397 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]); 9398 remotePointsNew[m].rank = rrank; 9399 ++m; 9400 } else if ((p >= cStart) && (p < cMax)) { 9401 /* Interior cells add new cells, faces, and edges */ 9402 for (r = 0; r < 8; ++r, ++m) { 9403 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9404 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9405 remotePointsNew[m].rank = rrank; 9406 } 9407 for (r = 0; r < 8; ++r, ++m) { 9408 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 9409 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*8 + r; 9410 remotePointsNew[m].rank = rrank; 9411 } 9412 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*1 + 0; 9413 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; 9414 remotePointsNew[m].rank = rrank; 9415 ++m; 9416 } else if ((p >= cMax) && (p < cEnd)) { 9417 /* Hybrid cells add new cells and faces */ 9418 for (r = 0; r < 4; ++r, ++m) { 9419 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9420 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9421 remotePointsNew[m].rank = rrank; 9422 } 9423 for (r = 0; r < 3; ++r, ++m) { 9424 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9425 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; 9426 remotePointsNew[m].rank = rrank; 9427 } 9428 } 9429 break; 9430 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9431 case REFINER_SIMPLEX_TO_HEX_3D: 9432 if ((p >= vStart) && (p < vEnd)) { 9433 /* Interior vertices stay the same */ 9434 localPointsNew[m] = vStartNew + (p - vStart); 9435 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9436 remotePointsNew[m].rank = rrank; 9437 ++m; 9438 } else if ((p >= eStart) && (p < eMax)) { 9439 /* Interior edges add new edges and vertex */ 9440 for (r = 0; r < 2; ++r, ++m) { 9441 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9442 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9443 remotePointsNew[m].rank = rrank; 9444 } 9445 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9446 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9447 remotePointsNew[m].rank = rrank; 9448 ++m; 9449 } else if ((p >= eMax) && (p < eEnd)) { 9450 /* Hybrid edges stay the same */ 9451 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (p - eMax); 9452 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]); 9453 remotePointsNew[m].rank = rrank; 9454 ++m; 9455 } else if ((p >= fStart) && (p < fMax)) { 9456 /* Interior faces add new faces, edges and a vertex */ 9457 for (r = 0; r < 3; ++r, ++m) { 9458 localPointsNew[m] = fStartNew + (p - fStart)*3 + r; 9459 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*3 + r; 9460 remotePointsNew[m].rank = rrank; 9461 } 9462 for (r = 0; r < 3; ++r, ++m) { 9463 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9464 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*3 + r; 9465 remotePointsNew[m].rank = rrank; 9466 } 9467 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9468 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9469 remotePointsNew[m].rank = rrank; 9470 ++m; 9471 } else if ((p >= fMax) && (p < fEnd)) { 9472 /* Interior hybrid faces add new faces and an edge */ 9473 for (r = 0; r < 2; ++r, ++m) { 9474 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9475 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; 9476 remotePointsNew[m].rank = rrank; 9477 } 9478 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9479 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]); 9480 remotePointsNew[m].rank = rrank; 9481 ++m; 9482 } else if ((p >= cStart) && (p < cMax)) { 9483 /* Interior cells add new cells, faces, edges, and a vertex */ 9484 for (r = 0; r < 4; ++r, ++m) { 9485 localPointsNew[m] = cStartNew + (p - cStart)*4 + r; 9486 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*4 + r; 9487 remotePointsNew[m].rank = rrank; 9488 } 9489 for (r = 0; r < 6; ++r, ++m) { 9490 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9491 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1]- rfStart[n])*3 + (rp - rcStart[n])*6 + r; 9492 remotePointsNew[m].rank = rrank; 9493 } 9494 for (r = 0; r < 4; ++r, ++m) { 9495 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9496 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; 9497 remotePointsNew[m].rank = rrank; 9498 } 9499 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 9500 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]); 9501 remotePointsNew[m].rank = rrank; 9502 ++m; 9503 } else if ((p >= cMax) && (p < cEnd)) { 9504 /* Interior hybrid cells add new cells, faces and an edge */ 9505 for (r = 0; r < 3; ++r, ++m) { 9506 localPointsNew[m] = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 9507 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*4 + (rp - rdepthMaxOld[n*(depth+1)+depth])*3 + r; 9508 remotePointsNew[m].rank = rrank; 9509 } 9510 for (r = 0; r < 3; ++r, ++m) { 9511 localPointsNew[m] = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 9512 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; 9513 remotePointsNew[m].rank = rrank; 9514 } 9515 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9516 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]); 9517 remotePointsNew[m].rank = rrank; 9518 ++m; 9519 } 9520 break; 9521 case REFINER_HEX_3D: 9522 case REFINER_HYBRID_HEX_3D: 9523 if ((p >= vStart) && (p < vEnd)) { 9524 /* Interior vertices stay the same */ 9525 localPointsNew[m] = vStartNew + (p - vStart); 9526 remotePointsNew[m].index = rvStartNew[n] + (rp - rvStart[n]); 9527 remotePointsNew[m].rank = rrank; 9528 ++m; 9529 } else if ((p >= eStart) && (p < eMax)) { 9530 /* Interior edges add new edges and vertex */ 9531 for (r = 0; r < 2; ++r, ++m) { 9532 localPointsNew[m] = eStartNew + (p - eStart)*2 + r; 9533 remotePointsNew[m].index = reStartNew[n] + (rp - reStart[n])*2 + r; 9534 remotePointsNew[m].rank = rrank; 9535 } 9536 localPointsNew[m] = vStartNew + (vEnd - vStart) + (p - eStart); 9537 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rp - reStart[n]); 9538 remotePointsNew[m].rank = rrank; 9539 ++m; 9540 } else if ((p >= eMax) && (p < eEnd)) { 9541 /* Hybrid edges stay the same */ 9542 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 9543 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]); 9544 remotePointsNew[m].rank = rrank; 9545 ++m; 9546 } else if ((p >= fStart) && (p < fMax)) { 9547 /* Interior faces add new faces, edges, and vertex */ 9548 for (r = 0; r < 4; ++r, ++m) { 9549 localPointsNew[m] = fStartNew + (p - fStart)*4 + r; 9550 remotePointsNew[m].index = rfStartNew[n] + (rp - rfStart[n])*4 + r; 9551 remotePointsNew[m].rank = rrank; 9552 } 9553 for (r = 0; r < 4; ++r, ++m) { 9554 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 9555 remotePointsNew[m].index = reStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n])*2 + (rp - rfStart[n])*4 + r; 9556 remotePointsNew[m].rank = rrank; 9557 } 9558 localPointsNew[m] = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 9559 remotePointsNew[m].index = rvStartNew[n] + rdepthSizeOld[n*(depth+1)+0] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rp - rfStart[n]); 9560 remotePointsNew[m].rank = rrank; 9561 ++m; 9562 } else if ((p >= fMax) && (p < fEnd)) { 9563 /* Hybrid faces add new faces and edges */ 9564 for (r = 0; r < 2; ++r, ++m) { 9565 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 9566 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; 9567 remotePointsNew[m].rank = rrank; 9568 } 9569 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (p - fMax); 9570 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]); 9571 remotePointsNew[m].rank = rrank; 9572 ++m; 9573 } else if ((p >= cStart) && (p < cMax)) { 9574 /* Interior cells add new cells, faces, edges, and vertex */ 9575 for (r = 0; r < 8; ++r, ++m) { 9576 localPointsNew[m] = cStartNew + (p - cStart)*8 + r; 9577 remotePointsNew[m].index = rcStartNew[n] + (rp - rcStart[n])*8 + r; 9578 remotePointsNew[m].rank = rrank; 9579 } 9580 for (r = 0; r < 12; ++r, ++m) { 9581 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 9582 remotePointsNew[m].index = rfStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n])*4 + (rp - rcStart[n])*12 + r; 9583 remotePointsNew[m].rank = rrank; 9584 } 9585 for (r = 0; r < 6; ++r, ++m) { 9586 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 9587 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; 9588 remotePointsNew[m].rank = rrank; 9589 } 9590 for (r = 0; r < 1; ++r, ++m) { 9591 localPointsNew[m] = vStartNew + (eMax - eStart) + (fMax - fStart) + (p - cStart) + r; 9592 remotePointsNew[m].index = rvStartNew[n] + (rdepthMaxOld[n*(depth+1)+1] - reStart[n]) + (rdepthMaxOld[n*(depth+1)+depth-1] - rfStart[n]) + (rp - rcStart[n]) + r; 9593 remotePointsNew[m].rank = rrank; 9594 } 9595 } else if ((p >= cMax) && (p < cEnd)) { 9596 /* Hybrid cells add new cells, faces, and edges */ 9597 for (r = 0; r < 4; ++r, ++m) { 9598 localPointsNew[m] = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 9599 remotePointsNew[m].index = rcStartNew[n] + (rdepthMaxOld[n*(depth+1)+depth] - rcStart[n])*8 + (rp - rdepthMaxOld[n*(depth+1)+depth])*4 + r; 9600 remotePointsNew[m].rank = rrank; 9601 } 9602 for (r = 0; r < 4; ++r, ++m) { 9603 localPointsNew[m] = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 9604 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; 9605 remotePointsNew[m].rank = rrank; 9606 } 9607 localPointsNew[m] = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (eEnd - eMax) + (fEnd - fMax) + (p - cMax); 9608 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]); 9609 remotePointsNew[m].rank = rrank; 9610 ++m; 9611 } 9612 break; 9613 default: 9614 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9615 } 9616 } 9617 if (m != numLeavesNew) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of leaf point %D should be %D", m, numLeavesNew); 9618 ierr = ISRestoreIndices(processRanks, &neighbors);CHKERRQ(ierr); 9619 ierr = ISDestroy(&processRanks);CHKERRQ(ierr); 9620 { 9621 PetscSFNode *rp, *rtmp; 9622 PetscInt *lp, *idx, *ltmp, i; 9623 9624 /* SF needs sorted leaves to correct calculate Gather */ 9625 ierr = PetscMalloc1(numLeavesNew,&idx);CHKERRQ(ierr); 9626 ierr = PetscMalloc1(numLeavesNew, &lp);CHKERRQ(ierr); 9627 ierr = PetscMalloc1(numLeavesNew, &rp);CHKERRQ(ierr); 9628 for (i = 0; i < numLeavesNew; ++i) { 9629 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); 9630 idx[i] = i; 9631 } 9632 ierr = PetscSortIntWithPermutation(numLeavesNew, localPointsNew, idx);CHKERRQ(ierr); 9633 for (i = 0; i < numLeavesNew; ++i) { 9634 lp[i] = localPointsNew[idx[i]]; 9635 rp[i] = remotePointsNew[idx[i]]; 9636 } 9637 ltmp = localPointsNew; 9638 localPointsNew = lp; 9639 rtmp = remotePointsNew; 9640 remotePointsNew = rp; 9641 ierr = PetscFree(idx);CHKERRQ(ierr); 9642 ierr = PetscFree(ltmp);CHKERRQ(ierr); 9643 ierr = PetscFree(rtmp);CHKERRQ(ierr); 9644 } 9645 ierr = PetscSFSetGraph(sfNew, pEndNew-pStartNew, numLeavesNew, localPointsNew, PETSC_OWN_POINTER, remotePointsNew, PETSC_OWN_POINTER);CHKERRQ(ierr); 9646 ierr = PetscFree5(rdepthSize,rvStartNew,reStartNew,rfStartNew,rcStartNew);CHKERRQ(ierr); 9647 ierr = PetscFree7(depthSizeOld,rdepthSizeOld,rdepthMaxOld,rvStart,reStart,rfStart,rcStart);CHKERRQ(ierr); 9648 PetscFunctionReturn(0); 9649 } 9650 9651 static PetscErrorCode CellRefinerCreateLabels(CellRefiner refiner, DM dm, PetscInt depthSize[], DM rdm) 9652 { 9653 PetscInt numLabels, l; 9654 PetscInt depth, newp, cStart, cEnd, cMax, vStart, vEnd, vMax, fStart, fEnd, fMax, eStart, eEnd, eMax, r; 9655 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 9656 PetscErrorCode ierr; 9657 9658 PetscFunctionBegin; 9659 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 9660 ierr = DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd);CHKERRQ(ierr); 9661 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 9662 ierr = DMPlexGetHeightStratum(dm, 1, &fStart, &fEnd);CHKERRQ(ierr); 9663 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 9664 if (refiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 9665 ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr); 9666 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, &eMax, &vMax);CHKERRQ(ierr); 9667 switch (refiner) { 9668 case REFINER_NOOP: 9669 case REFINER_SIMPLEX_1D: 9670 case REFINER_SIMPLEX_2D: 9671 case REFINER_SIMPLEX_TO_HEX_2D: 9672 case REFINER_HEX_2D: 9673 case REFINER_SIMPLEX_3D: 9674 case REFINER_HEX_3D: 9675 case REFINER_SIMPLEX_TO_HEX_3D: 9676 break; 9677 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9678 case REFINER_HYBRID_SIMPLEX_3D: 9679 case REFINER_HYBRID_HEX_3D: 9680 if (eMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No edge maximum specified in hybrid mesh"); 9681 case REFINER_HYBRID_SIMPLEX_2D: 9682 case REFINER_HYBRID_HEX_2D: 9683 if (fMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No face maximum specified in hybrid mesh"); 9684 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9685 if (cMax < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "No cell maximum specified in hybrid mesh"); 9686 break; 9687 default: 9688 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 9689 } 9690 cMax = cMax < 0 ? cEnd : cMax; 9691 fMax = fMax < 0 ? fEnd : fMax; 9692 eMax = eMax < 0 ? eEnd : eMax; 9693 for (l = 0; l < numLabels; ++l) { 9694 DMLabel label, labelNew; 9695 const char *lname; 9696 PetscBool isDepth, isCellType; 9697 IS valueIS; 9698 const PetscInt *values; 9699 PetscInt defVal; 9700 PetscInt numValues, val; 9701 9702 ierr = DMGetLabelName(dm, l, &lname);CHKERRQ(ierr); 9703 ierr = PetscStrcmp(lname, "depth", &isDepth);CHKERRQ(ierr); 9704 if (isDepth) continue; 9705 ierr = PetscStrcmp(lname, "celltype", &isCellType);CHKERRQ(ierr); 9706 if (isCellType) continue; 9707 ierr = DMCreateLabel(rdm, lname);CHKERRQ(ierr); 9708 ierr = DMGetLabel(dm, lname, &label);CHKERRQ(ierr); 9709 ierr = DMGetLabel(rdm, lname, &labelNew);CHKERRQ(ierr); 9710 ierr = DMLabelGetDefaultValue(label,&defVal);CHKERRQ(ierr); 9711 ierr = DMLabelSetDefaultValue(labelNew,defVal);CHKERRQ(ierr); 9712 ierr = DMLabelGetValueIS(label, &valueIS);CHKERRQ(ierr); 9713 ierr = ISGetLocalSize(valueIS, &numValues);CHKERRQ(ierr); 9714 ierr = ISGetIndices(valueIS, &values);CHKERRQ(ierr); 9715 for (val = 0; val < numValues; ++val) { 9716 IS pointIS; 9717 const PetscInt *points; 9718 PetscInt numPoints, n; 9719 9720 ierr = DMLabelGetStratumIS(label, values[val], &pointIS);CHKERRQ(ierr); 9721 ierr = ISGetLocalSize(pointIS, &numPoints);CHKERRQ(ierr); 9722 ierr = ISGetIndices(pointIS, &points);CHKERRQ(ierr); 9723 /* Ensure refined label is created with same number of strata as 9724 * original (even if no entries here). */ 9725 ierr = DMLabelAddStratum(labelNew, values[val]);CHKERRQ(ierr); 9726 for (n = 0; n < numPoints; ++n) { 9727 const PetscInt p = points[n]; 9728 switch (refiner) { 9729 case REFINER_SIMPLEX_1D: 9730 if ((p >= vStart) && (p < vEnd)) { 9731 /* Old vertices stay the same */ 9732 newp = vStartNew + (p - vStart); 9733 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9734 } else if ((p >= cStart) && (p < cEnd)) { 9735 /* Old cells add new cells and vertex */ 9736 newp = vStartNew + (vEnd - vStart) + (p - cStart); 9737 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9738 for (r = 0; r < 2; ++r) { 9739 newp = cStartNew + (p - cStart)*2 + r; 9740 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9741 } 9742 } 9743 break; 9744 case REFINER_SIMPLEX_2D: 9745 if ((p >= vStart) && (p < vEnd)) { 9746 /* Old vertices stay the same */ 9747 newp = vStartNew + (p - vStart); 9748 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9749 } else if ((p >= fStart) && (p < fEnd)) { 9750 /* Old faces add new faces and vertex */ 9751 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9752 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9753 for (r = 0; r < 2; ++r) { 9754 newp = fStartNew + (p - fStart)*2 + r; 9755 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9756 } 9757 } else if ((p >= cStart) && (p < cEnd)) { 9758 /* Old cells add new cells and interior faces */ 9759 for (r = 0; r < 4; ++r) { 9760 newp = cStartNew + (p - cStart)*4 + r; 9761 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9762 } 9763 for (r = 0; r < 3; ++r) { 9764 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9765 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9766 } 9767 } 9768 break; 9769 case REFINER_HYBRID_SIMPLEX_TO_HEX_2D: 9770 case REFINER_SIMPLEX_TO_HEX_2D: 9771 if ((p >= vStart) && (p < vEnd)) { 9772 /* Old vertices stay the same */ 9773 newp = vStartNew + (p - vStart); 9774 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9775 } else if ((p >= fStart) && (p < fEnd)) { 9776 /* Old faces add new faces and vertex */ 9777 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9778 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9779 for (r = 0; r < 2; ++r) { 9780 newp = fStartNew + (p - fStart)*2 + r; 9781 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9782 } 9783 } else if ((p >= cStart) && (p < cMax)) { 9784 /* Old cells add new cells, interior faces, and a vertex */ 9785 for (r = 0; r < 3; ++r) { 9786 newp = cStartNew + (p - cStart)*3 + r; 9787 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9788 } 9789 for (r = 0; r < 3; ++r) { 9790 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9791 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9792 } 9793 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9794 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9795 } else if ((p >= cMax) && (p < cEnd)) { 9796 /* Old hybrid cells add new cells, interior faces, and a vertex */ 9797 for (r = 0; r < 4; ++r) { 9798 newp = cStartNew + (cMax - cStart)*3 + (p - cMax)*4 + r; 9799 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9800 } 9801 for (r = 0; r < 4; ++r) { 9802 newp = fStartNew + (fEnd - fStart)*2 + (cMax - cStart)*3 + (p - cMax)*4 + r; 9803 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9804 } 9805 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + p; 9806 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9807 } 9808 break; 9809 case REFINER_HEX_2D: 9810 if ((p >= vStart) && (p < vEnd)) { 9811 /* Old vertices stay the same */ 9812 newp = vStartNew + (p - vStart); 9813 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9814 } else if ((p >= fStart) && (p < fEnd)) { 9815 /* Old faces add new faces and vertex */ 9816 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9817 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9818 for (r = 0; r < 2; ++r) { 9819 newp = fStartNew + (p - fStart)*2 + r; 9820 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9821 } 9822 } else if ((p >= cStart) && (p < cEnd)) { 9823 /* Old cells add new cells and interior faces and vertex */ 9824 for (r = 0; r < 4; ++r) { 9825 newp = cStartNew + (p - cStart)*4 + r; 9826 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9827 } 9828 for (r = 0; r < 4; ++r) { 9829 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9830 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9831 } 9832 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9833 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9834 } 9835 break; 9836 case REFINER_HYBRID_SIMPLEX_2D: 9837 if ((p >= vStart) && (p < vEnd)) { 9838 /* Old vertices stay the same */ 9839 newp = vStartNew + (p - vStart); 9840 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9841 } else if ((p >= fStart) && (p < fMax)) { 9842 /* Old interior faces add new faces and vertex */ 9843 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9844 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9845 for (r = 0; r < 2; ++r) { 9846 newp = fStartNew + (p - fStart)*2 + r; 9847 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9848 } 9849 } else if ((p >= fMax) && (p < fEnd)) { 9850 /* Old hybrid faces stay the same */ 9851 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9852 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9853 } else if ((p >= cStart) && (p < cMax)) { 9854 /* Old interior cells add new cells and interior faces */ 9855 for (r = 0; r < 4; ++r) { 9856 newp = cStartNew + (p - cStart)*4 + r; 9857 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9858 } 9859 for (r = 0; r < 3; ++r) { 9860 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*3 + r; 9861 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9862 } 9863 } else if ((p >= cMax) && (p < cEnd)) { 9864 /* Old hybrid cells add new cells and hybrid face */ 9865 for (r = 0; r < 2; ++r) { 9866 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9867 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9868 } 9869 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*3 + (p - cMax); 9870 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9871 } 9872 break; 9873 case REFINER_HYBRID_HEX_2D: 9874 if ((p >= vStart) && (p < vEnd)) { 9875 /* Old vertices stay the same */ 9876 newp = vStartNew + (p - vStart); 9877 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9878 } else if ((p >= fStart) && (p < fMax)) { 9879 /* Old interior faces add new faces and vertex */ 9880 newp = vStartNew + (vEnd - vStart) + (p - fStart); 9881 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9882 for (r = 0; r < 2; ++r) { 9883 newp = fStartNew + (p - fStart)*2 + r; 9884 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9885 } 9886 } else if ((p >= fMax) && (p < fEnd)) { 9887 /* Old hybrid faces stay the same */ 9888 newp = fStartNew + (fMax - fStart)*2 + (p - fMax); 9889 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9890 } else if ((p >= cStart) && (p < cMax)) { 9891 /* Old interior cells add new cells, interior faces, and vertex */ 9892 for (r = 0; r < 4; ++r) { 9893 newp = cStartNew + (p - cStart)*4 + r; 9894 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9895 } 9896 for (r = 0; r < 4; ++r) { 9897 newp = fStartNew + (fEnd - fStart)*2 + (p - cStart)*4 + r; 9898 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9899 } 9900 newp = vStartNew + (vEnd - vStart) + (fEnd - fStart) + (p - cStart); 9901 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9902 } else if ((p >= cMax) && (p < cEnd)) { 9903 /* Old hybrid cells add new cells and hybrid face */ 9904 for (r = 0; r < 2; ++r) { 9905 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*2 + r; 9906 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9907 } 9908 newp = fStartNew + (fMax - fStart)*2 + (cMax - cStart)*4 + (p - cMax); 9909 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9910 } 9911 break; 9912 case REFINER_SIMPLEX_3D: 9913 if ((p >= vStart) && (p < vEnd)) { 9914 /* Old vertices stay the same */ 9915 newp = vStartNew + (p - vStart); 9916 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9917 } else if ((p >= eStart) && (p < eEnd)) { 9918 /* Old edges add new edges and vertex */ 9919 for (r = 0; r < 2; ++r) { 9920 newp = eStartNew + (p - eStart)*2 + r; 9921 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9922 } 9923 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9924 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9925 } else if ((p >= fStart) && (p < fEnd)) { 9926 /* Old faces add new faces and edges */ 9927 for (r = 0; r < 4; ++r) { 9928 newp = fStartNew + (p - fStart)*4 + r; 9929 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9930 } 9931 for (r = 0; r < 3; ++r) { 9932 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*3 + r; 9933 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9934 } 9935 } else if ((p >= cStart) && (p < cEnd)) { 9936 /* Old cells add new cells and interior faces and edges */ 9937 for (r = 0; r < 8; ++r) { 9938 newp = cStartNew + (p - cStart)*8 + r; 9939 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9940 } 9941 for (r = 0; r < 8; ++r) { 9942 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*8 + r; 9943 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9944 } 9945 for (r = 0; r < 1; ++r) { 9946 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*3 + (p - cStart)*1 + r; 9947 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9948 } 9949 } 9950 break; 9951 case REFINER_HYBRID_SIMPLEX_TO_HEX_3D: 9952 case REFINER_SIMPLEX_TO_HEX_3D: 9953 if ((p >= vStart) && (p < vEnd)) { 9954 /* Old vertices stay the same */ 9955 newp = vStartNew + (p - vStart); 9956 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9957 } else if ((p >= eStart) && (p < eMax)) { 9958 /* Interior edges add new edges and vertex */ 9959 for (r = 0; r < 2; ++r) { 9960 newp = eStartNew + (p - eStart)*2 + r; 9961 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9962 } 9963 newp = vStartNew + (vEnd - vStart) + (p - eStart); 9964 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9965 } else if ((p >= eMax) && (p < eEnd)) { 9966 /* Hybrid edges stay the same */ 9967 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + p - eMax; 9968 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9969 } else if ((p >= fStart) && (p < fMax)) { 9970 /* Old faces add new faces, edges and a vertex */ 9971 for (r = 0; r < 3; ++r) { 9972 newp = fStartNew + (p - fStart)*3 + r; 9973 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9974 } 9975 for (r = 0; r < 3; ++r) { 9976 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 9977 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9978 } 9979 } else if ((p >= fMax) && (p < fEnd)) { 9980 /* Old hybrid faces add new faces and an edge */ 9981 for (r = 0; r < 2; ++r) { 9982 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (p - fMax)*2 + r; 9983 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9984 } 9985 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (p - fMax); 9986 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9987 } else if ((p >= cStart) && (p < cMax)) { 9988 /* Old cells add new cells and interior faces and edges and a vertex */ 9989 for (r = 0; r < 4; ++r) { 9990 newp = cStartNew + (p - cStart)*4 + r; 9991 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9992 } 9993 for (r = 0; r < 6; ++r) { 9994 newp = fStartNew + (fMax - fStart)*3 + (p - cStart)*6 + r; 9995 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 9996 } 9997 for (r = 0; r < 4; ++r) { 9998 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart)*4 + r; 9999 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10000 } 10001 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + p - cStart; 10002 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10003 } else if ((p >= cMax) && (p < cEnd)) { 10004 /* Old hybrid cells add new cells and interior faces and an edge */ 10005 for (r = 0; r < 3; ++r) { 10006 newp = cStartNew + (cMax - cStart)*4 + (p - cMax)*3 + r; 10007 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10008 } 10009 for (r = 0; r < 3; ++r) { 10010 newp = fStartNew + (fMax - fStart)*3 + (cMax - cStart)*6 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 10011 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10012 } 10013 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart)*4 + (eEnd - eMax) + (fEnd - fMax) + p - cMax; 10014 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10015 } 10016 break; 10017 case REFINER_HYBRID_SIMPLEX_3D: 10018 if ((p >= vStart) && (p < vEnd)) { 10019 /* Interior vertices stay the same */ 10020 newp = vStartNew + (p - vStart); 10021 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10022 } else if ((p >= eStart) && (p < eMax)) { 10023 /* Interior edges add new edges and vertex */ 10024 for (r = 0; r < 2; ++r) { 10025 newp = eStartNew + (p - eStart)*2 + r; 10026 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10027 } 10028 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10029 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10030 } else if ((p >= eMax) && (p < eEnd)) { 10031 /* Hybrid edges stay the same */ 10032 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - eMax); 10033 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10034 } else if ((p >= fStart) && (p < fMax)) { 10035 /* Interior faces add new faces and edges */ 10036 for (r = 0; r < 4; ++r) { 10037 newp = fStartNew + (p - fStart)*4 + r; 10038 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10039 } 10040 for (r = 0; r < 3; ++r) { 10041 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*3 + r; 10042 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10043 } 10044 } else if ((p >= fMax) && (p < fEnd)) { 10045 /* Hybrid faces add new faces and edges */ 10046 for (r = 0; r < 2; ++r) { 10047 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (p - fMax)*2 + r; 10048 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10049 } 10050 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (cMax - cStart) + (p - fMax); 10051 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10052 } else if ((p >= cStart) && (p < cMax)) { 10053 /* Interior cells add new cells, faces, and edges */ 10054 for (r = 0; r < 8; ++r) { 10055 newp = cStartNew + (p - cStart)*8 + r; 10056 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10057 } 10058 for (r = 0; r < 8; ++r) { 10059 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*8 + r; 10060 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10061 } 10062 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*3 + (p - cStart); 10063 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10064 } else if ((p >= cMax) && (p < cEnd)) { 10065 /* Hybrid cells add new cells and faces */ 10066 for (r = 0; r < 4; ++r) { 10067 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10068 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10069 } 10070 for (r = 0; r < 3; ++r) { 10071 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*8 + (fEnd - fMax)*2 + (p - cMax)*3 + r; 10072 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10073 } 10074 } 10075 break; 10076 case REFINER_HEX_3D: 10077 if ((p >= vStart) && (p < vEnd)) { 10078 /* Old vertices stay the same */ 10079 newp = vStartNew + (p - vStart); 10080 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10081 } else if ((p >= eStart) && (p < eEnd)) { 10082 /* Old edges add new edges and vertex */ 10083 for (r = 0; r < 2; ++r) { 10084 newp = eStartNew + (p - eStart)*2 + r; 10085 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10086 } 10087 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10088 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10089 } else if ((p >= fStart) && (p < fEnd)) { 10090 /* Old faces add new faces, edges, and vertex */ 10091 for (r = 0; r < 4; ++r) { 10092 newp = fStartNew + (p - fStart)*4 + r; 10093 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10094 } 10095 for (r = 0; r < 4; ++r) { 10096 newp = eStartNew + (eEnd - eStart)*2 + (p - fStart)*4 + r; 10097 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10098 } 10099 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (p - fStart); 10100 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10101 } else if ((p >= cStart) && (p < cEnd)) { 10102 /* Old cells add new cells, faces, edges, and vertex */ 10103 for (r = 0; r < 8; ++r) { 10104 newp = cStartNew + (p - cStart)*8 + r; 10105 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10106 } 10107 for (r = 0; r < 12; ++r) { 10108 newp = fStartNew + (fEnd - fStart)*4 + (p - cStart)*12 + r; 10109 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10110 } 10111 for (r = 0; r < 6; ++r) { 10112 newp = eStartNew + (eEnd - eStart)*2 + (fEnd - fStart)*4 + (p - cStart)*6 + r; 10113 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10114 } 10115 newp = vStartNew + (vEnd - vStart) + (eEnd - eStart) + (fEnd - fStart) + (p - cStart); 10116 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10117 } 10118 break; 10119 case REFINER_HYBRID_HEX_3D: 10120 if ((p >= vStart) && (p < vEnd)) { 10121 /* Interior vertices stay the same */ 10122 newp = vStartNew + (p - vStart); 10123 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10124 } else if ((p >= eStart) && (p < eMax)) { 10125 /* Interior edges add new edges and vertex */ 10126 for (r = 0; r < 2; ++r) { 10127 newp = eStartNew + (p - eStart)*2 + r; 10128 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10129 } 10130 newp = vStartNew + (vEnd - vStart) + (p - eStart); 10131 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10132 } else if ((p >= eMax) && (p < eEnd)) { 10133 /* Hybrid edges stay the same */ 10134 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - eMax); 10135 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10136 } else if ((p >= fStart) && (p < fMax)) { 10137 /* Interior faces add new faces, edges, and vertex */ 10138 for (r = 0; r < 4; ++r) { 10139 newp = fStartNew + (p - fStart)*4 + r; 10140 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10141 } 10142 for (r = 0; r < 4; ++r) { 10143 newp = eStartNew + (eMax - eStart)*2 + (p - fStart)*4 + r; 10144 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10145 } 10146 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (p - fStart); 10147 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10148 } else if ((p >= fMax) && (p < fEnd)) { 10149 /* Hybrid faces add new faces and edges */ 10150 for (r = 0; r < 2; ++r) { 10151 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (p - fMax)*2 + r; 10152 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10153 } 10154 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (p - fMax); 10155 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10156 } else if ((p >= cStart) && (p < cMax)) { 10157 /* Interior cells add new cells, faces, edges, and vertex */ 10158 for (r = 0; r < 8; ++r) { 10159 newp = cStartNew + (p - cStart)*8 + r; 10160 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10161 } 10162 for (r = 0; r < 12; ++r) { 10163 newp = fStartNew + (fMax - fStart)*4 + (p - cStart)*12 + r; 10164 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10165 } 10166 for (r = 0; r < 6; ++r) { 10167 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (p - cStart)*6 + r; 10168 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10169 } 10170 newp = vStartNew + (vEnd - vStart) + (eMax - eStart) + (fMax - fStart) + (p - cStart); 10171 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10172 } else if ((p >= cMax) && (p < cEnd)) { 10173 /* Hybrid cells add new cells, faces, and edges */ 10174 for (r = 0; r < 4; ++r) { 10175 newp = cStartNew + (cMax - cStart)*8 + (p - cMax)*4 + r; 10176 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10177 } 10178 for (r = 0; r < 4; ++r) { 10179 newp = fStartNew + (fMax - fStart)*4 + (cMax - cStart)*12 + (fEnd - fMax)*2 + (p - cMax)*4 + r; 10180 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10181 } 10182 newp = eStartNew + (eMax - eStart)*2 + (fMax - fStart)*4 + (cMax - cStart)*6 + (fEnd - fMax) + (p - cMax); 10183 ierr = DMLabelSetValue(labelNew, newp, values[val]);CHKERRQ(ierr); 10184 } 10185 break; 10186 default: 10187 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[refiner]); 10188 } 10189 } 10190 ierr = ISRestoreIndices(pointIS, &points);CHKERRQ(ierr); 10191 ierr = ISDestroy(&pointIS);CHKERRQ(ierr); 10192 } 10193 ierr = ISRestoreIndices(valueIS, &values);CHKERRQ(ierr); 10194 ierr = ISDestroy(&valueIS);CHKERRQ(ierr); 10195 } 10196 PetscFunctionReturn(0); 10197 } 10198 10199 /* This will only work for interpolated meshes */ 10200 PetscErrorCode DMPlexRefineUniform_Internal(DM dm, CellRefiner cellRefiner, DM *dmRefined) 10201 { 10202 DM rdm; 10203 PetscInt *depthSize; 10204 PetscInt dim, embedDim, depth = 0, d, pStart = 0, pEnd = 0; 10205 PetscErrorCode ierr; 10206 10207 PetscFunctionBegin; 10208 ierr = DMCreate(PetscObjectComm((PetscObject)dm), &rdm);CHKERRQ(ierr); 10209 ierr = DMSetType(rdm, DMPLEX);CHKERRQ(ierr); 10210 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10211 ierr = DMSetDimension(rdm, dim);CHKERRQ(ierr); 10212 ierr = DMGetCoordinateDim(dm, &embedDim);CHKERRQ(ierr); 10213 ierr = DMSetCoordinateDim(rdm, embedDim);CHKERRQ(ierr); 10214 /* Calculate number of new points of each depth */ 10215 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10216 if (depth >= 0 && dim != depth) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_WRONG, "Mesh must be interpolated for regular refinement"); 10217 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10218 ierr = PetscMemzero(depthSize, (depth+1) * sizeof(PetscInt));CHKERRQ(ierr); 10219 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10220 /* Step 1: Set chart */ 10221 for (d = 0; d <= depth; ++d) pEnd += depthSize[d]; 10222 ierr = DMPlexSetChart(rdm, pStart, pEnd);CHKERRQ(ierr); 10223 /* Step 2: Set cone/support sizes (automatically stratifies) */ 10224 ierr = CellRefinerSetConeSizes(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10225 /* Step 3: Setup refined DM */ 10226 ierr = DMSetUp(rdm);CHKERRQ(ierr); 10227 /* Step 4: Set cones and supports (automatically symmetrizes) */ 10228 ierr = CellRefinerSetCones(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10229 /* Step 5: Create pointSF */ 10230 ierr = CellRefinerCreateSF(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10231 /* Step 6: Create labels */ 10232 ierr = CellRefinerCreateLabels(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10233 /* Step 7: Set coordinates */ 10234 ierr = CellRefinerSetCoordinates(cellRefiner, dm, depthSize, rdm);CHKERRQ(ierr); 10235 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10236 10237 *dmRefined = rdm; 10238 PetscFunctionReturn(0); 10239 } 10240 10241 /*@ 10242 DMPlexCreateCoarsePointIS - Creates an IS covering the coarse DM chart with the fine points as data 10243 10244 Input Parameter: 10245 . dm - The coarse DM 10246 10247 Output Parameter: 10248 . fpointIS - The IS of all the fine points which exist in the original coarse mesh 10249 10250 Level: developer 10251 10252 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexCreateSubpointIS() 10253 @*/ 10254 PetscErrorCode DMPlexCreateCoarsePointIS(DM dm, IS *fpointIS) 10255 { 10256 CellRefiner cellRefiner; 10257 PetscInt *depthSize, *fpoints; 10258 PetscInt cStartNew = 0, vStartNew = 0, fStartNew = 0, eStartNew = 0; 10259 PetscInt depth, pStart, pEnd, p, vStart, vEnd, v; 10260 PetscErrorCode ierr; 10261 10262 PetscFunctionBegin; 10263 ierr = DMPlexGetDepth(dm, &depth);CHKERRQ(ierr); 10264 ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr); 10265 ierr = DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd);CHKERRQ(ierr); 10266 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10267 ierr = PetscMalloc1(depth+1, &depthSize);CHKERRQ(ierr); 10268 ierr = CellRefinerGetSizes(cellRefiner, dm, depthSize);CHKERRQ(ierr); 10269 if (cellRefiner) {ierr = GetDepthStart_Private(depth, depthSize, &cStartNew, &fStartNew, &eStartNew, &vStartNew);CHKERRQ(ierr);} 10270 ierr = PetscMalloc1(pEnd-pStart,&fpoints);CHKERRQ(ierr); 10271 for (p = 0; p < pEnd-pStart; ++p) fpoints[p] = -1; 10272 switch (cellRefiner) { 10273 case REFINER_SIMPLEX_1D: 10274 case REFINER_SIMPLEX_2D: 10275 case REFINER_HYBRID_SIMPLEX_2D: 10276 case REFINER_HEX_2D: 10277 case REFINER_HYBRID_HEX_2D: 10278 case REFINER_SIMPLEX_3D: 10279 case REFINER_HYBRID_SIMPLEX_3D: 10280 case REFINER_HEX_3D: 10281 case REFINER_HYBRID_HEX_3D: 10282 for (v = vStart; v < vEnd; ++v) fpoints[v-pStart] = vStartNew + (v - vStart); 10283 break; 10284 default: 10285 SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Unknown cell refiner %s", CellRefiners[cellRefiner]); 10286 } 10287 ierr = ISCreateGeneral(PETSC_COMM_SELF, pEnd-pStart, fpoints, PETSC_OWN_POINTER, fpointIS);CHKERRQ(ierr); 10288 ierr = PetscFree(depthSize);CHKERRQ(ierr); 10289 PetscFunctionReturn(0); 10290 } 10291 10292 /*@ 10293 DMPlexSetRefinementUniform - Set the flag for uniform refinement 10294 10295 Input Parameters: 10296 + dm - The DM 10297 - refinementUniform - The flag for uniform refinement 10298 10299 Level: developer 10300 10301 .seealso: DMRefine(), DMPlexGetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10302 @*/ 10303 PetscErrorCode DMPlexSetRefinementUniform(DM dm, PetscBool refinementUniform) 10304 { 10305 DM_Plex *mesh = (DM_Plex*) dm->data; 10306 10307 PetscFunctionBegin; 10308 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10309 mesh->refinementUniform = refinementUniform; 10310 PetscFunctionReturn(0); 10311 } 10312 10313 /*@ 10314 DMPlexGetRefinementUniform - Retrieve the flag for uniform refinement 10315 10316 Input Parameter: 10317 . dm - The DM 10318 10319 Output Parameter: 10320 . refinementUniform - The flag for uniform refinement 10321 10322 Level: developer 10323 10324 .seealso: DMRefine(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10325 @*/ 10326 PetscErrorCode DMPlexGetRefinementUniform(DM dm, PetscBool *refinementUniform) 10327 { 10328 DM_Plex *mesh = (DM_Plex*) dm->data; 10329 10330 PetscFunctionBegin; 10331 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10332 PetscValidPointer(refinementUniform, 2); 10333 *refinementUniform = mesh->refinementUniform; 10334 PetscFunctionReturn(0); 10335 } 10336 10337 /*@ 10338 DMPlexSetRefinementLimit - Set the maximum cell volume for refinement 10339 10340 Input Parameters: 10341 + dm - The DM 10342 - refinementLimit - The maximum cell volume in the refined mesh 10343 10344 Level: developer 10345 10346 .seealso: DMRefine(), DMPlexGetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10347 @*/ 10348 PetscErrorCode DMPlexSetRefinementLimit(DM dm, PetscReal refinementLimit) 10349 { 10350 DM_Plex *mesh = (DM_Plex*) dm->data; 10351 10352 PetscFunctionBegin; 10353 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10354 mesh->refinementLimit = refinementLimit; 10355 PetscFunctionReturn(0); 10356 } 10357 10358 /*@ 10359 DMPlexGetRefinementLimit - Retrieve the maximum cell volume for refinement 10360 10361 Input Parameter: 10362 . dm - The DM 10363 10364 Output Parameter: 10365 . refinementLimit - The maximum cell volume in the refined mesh 10366 10367 Level: developer 10368 10369 .seealso: DMRefine(), DMPlexSetRefinementLimit(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform() 10370 @*/ 10371 PetscErrorCode DMPlexGetRefinementLimit(DM dm, PetscReal *refinementLimit) 10372 { 10373 DM_Plex *mesh = (DM_Plex*) dm->data; 10374 10375 PetscFunctionBegin; 10376 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10377 PetscValidPointer(refinementLimit, 2); 10378 /* if (mesh->refinementLimit < 0) = getMaxVolume()/2.0; */ 10379 *refinementLimit = mesh->refinementLimit; 10380 PetscFunctionReturn(0); 10381 } 10382 10383 /*@ 10384 DMPlexSetRefinementFunction - Set the function giving the maximum cell volume for refinement 10385 10386 Input Parameters: 10387 + dm - The DM 10388 - refinementFunc - Function giving the maximum cell volume in the refined mesh 10389 10390 Note: The calling sequence is refinementFunc(coords, limit) 10391 $ coords - Coordinates of the current point, usually a cell centroid 10392 $ limit - The maximum cell volume for a cell containing this point 10393 10394 Level: developer 10395 10396 .seealso: DMRefine(), DMPlexGetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10397 @*/ 10398 PetscErrorCode DMPlexSetRefinementFunction(DM dm, PetscErrorCode (*refinementFunc)(const PetscReal [], PetscReal *)) 10399 { 10400 DM_Plex *mesh = (DM_Plex*) dm->data; 10401 10402 PetscFunctionBegin; 10403 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10404 mesh->refinementFunc = refinementFunc; 10405 PetscFunctionReturn(0); 10406 } 10407 10408 /*@ 10409 DMPlexGetRefinementFunction - Get the function giving the maximum cell volume for refinement 10410 10411 Input Parameter: 10412 . dm - The DM 10413 10414 Output Parameter: 10415 . refinementFunc - Function giving the maximum cell volume in the refined mesh 10416 10417 Note: The calling sequence is refinementFunc(coords, limit) 10418 $ coords - Coordinates of the current point, usually a cell centroid 10419 $ limit - The maximum cell volume for a cell containing this point 10420 10421 Level: developer 10422 10423 .seealso: DMRefine(), DMPlexSetRefinementFunction(), DMPlexGetRefinementUniform(), DMPlexSetRefinementUniform(), DMPlexGetRefinementLimit(), DMPlexSetRefinementLimit() 10424 @*/ 10425 PetscErrorCode DMPlexGetRefinementFunction(DM dm, PetscErrorCode (**refinementFunc)(const PetscReal [], PetscReal *)) 10426 { 10427 DM_Plex *mesh = (DM_Plex*) dm->data; 10428 10429 PetscFunctionBegin; 10430 PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 10431 PetscValidPointer(refinementFunc, 2); 10432 *refinementFunc = mesh->refinementFunc; 10433 PetscFunctionReturn(0); 10434 } 10435 10436 PetscErrorCode DMPlexGetCellRefiner_Internal(DM dm, CellRefiner *cellRefiner) 10437 { 10438 DMPolytopeType ct; 10439 PetscInt dim, cStart, cEnd, cMax, fMax; 10440 PetscErrorCode ierr; 10441 10442 PetscFunctionBegin; 10443 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 10444 ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr); 10445 if (cEnd <= cStart) {*cellRefiner = REFINER_NOOP; PetscFunctionReturn(0);} 10446 ierr = DMPlexGetHybridBounds(dm, &cMax, &fMax, NULL, NULL);CHKERRQ(ierr); 10447 /* TODO Must tag hybrid cells with correct cell types */ 10448 ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 10449 switch (ct) { 10450 case DM_POLYTOPE_SEGMENT: *cellRefiner = REFINER_SIMPLEX_1D; break; 10451 case DM_POLYTOPE_TRIANGLE: if (cMax >= 0) {*cellRefiner = REFINER_HYBRID_SIMPLEX_2D; break;} 10452 else {*cellRefiner = REFINER_SIMPLEX_2D; break;} 10453 case DM_POLYTOPE_QUADRILATERAL: if (cMax >= 0) {*cellRefiner = REFINER_HYBRID_HEX_2D; break;} /* Why did this have fMax >= 0 ??? */ 10454 else {*cellRefiner = REFINER_HEX_2D; break;} 10455 case DM_POLYTOPE_TETRAHEDRON: if (cMax >= 0) {*cellRefiner = REFINER_HYBRID_SIMPLEX_3D; break;} 10456 else {*cellRefiner = REFINER_SIMPLEX_3D; break;} 10457 case DM_POLYTOPE_HEXAHEDRON: if (cMax >= 0) {*cellRefiner = REFINER_HYBRID_HEX_3D; break;} 10458 else {*cellRefiner = REFINER_HEX_3D; break;} 10459 case DM_POLYTOPE_SEG_PRISM_TENSOR: *cellRefiner = REFINER_HYBRID_SIMPLEX_2D; break; 10460 case DM_POLYTOPE_TRI_PRISM_TENSOR: *cellRefiner = REFINER_HYBRID_SIMPLEX_3D; break; 10461 case DM_POLYTOPE_QUAD_PRISM_TENSOR: *cellRefiner = REFINER_HYBRID_HEX_3D; break; 10462 default: SETERRQ2(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "No cell refiner for cell %D with type %s", cStart, DMPolytopeTypes[ct]); 10463 } 10464 PetscFunctionReturn(0); 10465 } 10466 10467 PetscErrorCode DMRefine_Plex(DM dm, MPI_Comm comm, DM *dmRefined) 10468 { 10469 PetscBool isUniform; 10470 PetscErrorCode ierr; 10471 10472 PetscFunctionBegin; 10473 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10474 if (isUniform) { 10475 CellRefiner cellRefiner; 10476 PetscBool localized; 10477 10478 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10479 ierr = DMPlexGetCellRefiner_Internal(dm, &cellRefiner);CHKERRQ(ierr); 10480 ierr = DMPlexRefineUniform_Internal(dm, cellRefiner, dmRefined);CHKERRQ(ierr); 10481 ierr = DMPlexSetRegularRefinement(*dmRefined, PETSC_TRUE);CHKERRQ(ierr); 10482 ierr = DMCopyBoundary(dm, *dmRefined);CHKERRQ(ierr); 10483 if (localized) {ierr = DMLocalizeCoordinates(*dmRefined);CHKERRQ(ierr);} 10484 } else { 10485 ierr = DMPlexRefine_Internal(dm, NULL, dmRefined);CHKERRQ(ierr); 10486 } 10487 PetscFunctionReturn(0); 10488 } 10489 10490 PetscErrorCode DMRefineHierarchy_Plex(DM dm, PetscInt nlevels, DM dmRefined[]) 10491 { 10492 DM cdm = dm; 10493 PetscInt r; 10494 PetscBool isUniform, localized; 10495 PetscErrorCode ierr; 10496 10497 PetscFunctionBegin; 10498 ierr = DMPlexGetRefinementUniform(dm, &isUniform);CHKERRQ(ierr); 10499 ierr = DMGetCoordinatesLocalized(dm, &localized);CHKERRQ(ierr); 10500 if (isUniform) { 10501 for (r = 0; r < nlevels; ++r) { 10502 CellRefiner cellRefiner; 10503 10504 ierr = DMPlexGetCellRefiner_Internal(cdm, &cellRefiner);CHKERRQ(ierr); 10505 ierr = DMPlexRefineUniform_Internal(cdm, cellRefiner, &dmRefined[r]);CHKERRQ(ierr); 10506 ierr = DMSetCoarsenLevel(dmRefined[r], cdm->leveldown);CHKERRQ(ierr); 10507 ierr = DMSetRefineLevel(dmRefined[r], cdm->levelup+1);CHKERRQ(ierr); 10508 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10509 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10510 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10511 ierr = DMPlexSetRegularRefinement(dmRefined[r], PETSC_TRUE);CHKERRQ(ierr); 10512 cdm = dmRefined[r]; 10513 } 10514 } else { 10515 for (r = 0; r < nlevels; ++r) { 10516 ierr = DMRefine(cdm, PetscObjectComm((PetscObject) dm), &dmRefined[r]);CHKERRQ(ierr); 10517 ierr = DMCopyBoundary(cdm, dmRefined[r]);CHKERRQ(ierr); 10518 if (localized) {ierr = DMLocalizeCoordinates(dmRefined[r]);CHKERRQ(ierr);} 10519 ierr = DMSetCoarseDM(dmRefined[r], cdm);CHKERRQ(ierr); 10520 cdm = dmRefined[r]; 10521 } 10522 } 10523 PetscFunctionReturn(0); 10524 } 10525